Tuesday, May 31, 2016

Cracking Passwords

The problem

We have to face the following situation: we want to migrate our customers from one system (legacy) to another. Customer data (emails,, address, login) are the easy part. What about passwords; wouldn't be nice that the users login into the new system with their actual passwords?

Technological we weren't lucky:

so we can't just copy also the hashed password

Remark: by no means assertions in this blog should be considered the final truth: while facts and samples were tested I might missed some options that might further enhance your experience.

The solution

As I hope you understand this is just used for documenting some cracking password tools not a recommendation for a best practice: imagine what customers would thing about your ethics if realizing what you have done...

So, coming back to the topic: try some cracking tools, do a reverse engineering of passwords and then compute the target SHA-256 hash.

Problem solved! Well, not exactly. Having a technical solution is not always equivalent with having the problem actually solved, as we will discover soon.

Tools investigated:

John

Basic usage is straight forward:

  • Export hashed password in accepted text format: <username>:<crypt(3)> per line; something like florin:$1$florin$1Y2H3TC.KoSWWN7v9hUZ0.
  • run john: john passwords.txt

Several variations

Single mode

Run just rules from the configuration file section [List.Rules:Single] (see john.ini)

john --single passwords.txt

Incremental

Based on the Incremental:XXX section definition john will try (brute force) all combinations. See below a customized MyAlpha section:

[Incremental:MyAlpha]
File = $JOHN/alpha.chr
MinLen = 1
MaxLen = 6
CharCount = 26

rem john -i=MyAlpha ../Passwords.txt

Remarks

The good news

Not so good for customers actually: the single mode will be able to quick (in a matter of seconds for the 1000 samples I used) solve 10% of the users by using common patterns applied to their user names. This might not be valid for other samples

The bad news

john is single threaded, so I had to split the passwords.txt into four files and run it in parallel. After several days just some additional tens of passwords were discovered, (1, 2 or 3 letters/digits) so I cad say good by to the rest

Hashcat

It comes into two flavours:

If you are lucky enough to have one of the two supported GPU' (AMD or Nvidia) go for the second (several magnitude times faster in my samples!).

The usage looked more complicated than for john (might worth to explore dipper); what I used sort of extensively was the mask attack (https://hashcat.net/wiki/doku.php?id=mask_attack).

Password text file should contain (per line) just the ctrypto(3) part, no user names

Samples (should be the same for CPU based hashcat (hashcat-cli64.exe)):

cudaHashcat64.exe --hash-type=500 -a 3 CryptHashes.txt ?l?l?l?l?l
cudaHashcat64.exe --hash-type=500 -a 3 CryptHashes.txt ?l?l?l?d
cudaHashcat64.exe --hash-type=500 -a 3 CryptHashes.txt ?l?l?l?l?d
cudaHashcat64.exe --hash-type=500 -a 3 CryptHashes.txt ?l?l?l?l?l?d
cudaHashcat64.exe --hash-type=500 -a 3 CryptHashes.txt ?l?l?l?l?l?l?d
cudaHashcat64.exe --increment --increment-min=4 --hash-type=500 -a 3 CryptHashes.txt -1 ?l?d ?1?1?1?1?1?1

You can use up to 4 custom char set definitions, something like:

cudaHashcat64.exe --hash-type=500 -a 3 CryptHashes.txt -1 ?u -2 ?l -3 ?d ?1?2?2?2?3?3

This will mean try all combinations that start with an upper letter, contains 3 lower case letters and ends up into two figures.

Best guess: there is a tool that based on mask can generate word files on which you could run hashcat by applying rules. Just putting (once again, as best guess) together what I remember from reading chaotically the documentation.

The Good News

If passwords are short enough (5~6 in length) and you will be able to guess the right mask the GPU based version will might do the job (like 20 hours for ?l?l?l?l?l mask). CPU load will be minimal.

The Bad News

If the users were clever enough to use longer passwords, combination of Upper/lower/digits/special character spread all over the string you are stuck in months/years of waiting

Common Remarks

Found passwords are stored in john.pot, respectively *hashcat.pot Both tools are re-start-able:

  • cold restart: just restart the process and found passwords are skipped (but the process is started from the beginning on a smaller list of hashes)
  • warm restart, based on a saved session which will actually restart were from it was interrupted:
    • tested tor cudaHashcat: provide a session name at first run and use that session name for restore
cudaHashcat64.exe --hash-type=500 -a 3 --session=Session CryptHashes10.txt  -1 abcdefghijlmnoprstuv ?1?1?1?1?1?1
...
cudaHashcat64.exe --session=Session --restore

Be aware: Do not quit immediately after restarting in restore mode; wait till the current restore point changes from zero to something near the actual progress value otherwise you will loose all work done so far. This is normal behaviour as stated on some answers on forum

IyBUaGUgcHJvYmxlbQ0KDQpXZSBoYXZlIHRvIGZhY2UgdGhlIGZvbGxvd2luZyBzaXR1YXRpb246IHdlIHdhbnQgdG8gbWlncmF0ZSBvdXIgY3VzdG9tZXJzIGZyb20gb25lIHN5c3RlbSAobGVnYWN5KSB0byBhbm90aGVyLiBDdXN0b21lciBkYXRhIChlbWFpbHMsLCBhZGRyZXNzLCBsb2dpbikgYXJlIHRoZSBlYXN5IHBhcnQuIFdoYXQgYWJvdXQgcGFzc3dvcmRzOyB3b3VsZG4ndCBiZSBuaWNlIHRoYXQgdGhlIHVzZXJzIGxvZ2luIGludG8gdGhlIG5ldyBzeXN0ZW0gd2l0aCB0aGVpciBhY3R1YWwgcGFzc3dvcmRzPw0KDQpUZWNobm9sb2dpY2FsIHdlIHdlcmVuJ3QgbHVja3k6DQotIHRoZSBvbGQgc3lzdGVtIHN0b3JlcyBwYXNzd29yZHMgYXMgY3J5cHQoMykgb3ZlciBNRDUgKGFsZ29yaXRobSBJRCAxKTsgc2VlIFtodHRwczovL3F1aWNraGFzaC5jb20vY3J5cHQzLW1kNS1vbmxpbmVdKGh0dHBzOi8vcXVpY2toYXNoLmNvbS9jcnlwdDMtbWQ1LW9ubGluZSkgaWYgeW91IHdhbnQgZ2VuZXJhdGUgc29tZSB0ZXN0IGRhdGEuDQotIHRoZSBuZXcgc3lzdGVtIGFjY2VwdHMgU0hBLTI1Ng0KDQpzbyB3ZSBjYW4ndCBqdXN0IGNvcHkgYWxzbyB0aGUgaGFzaGVkIHBhc3N3b3JkDQoNCioqUmVtYXJrKio6IGJ5IG5vIG1lYW5zIGFzc2VydGlvbnMgaW4gdGhpcyBibG9nIHNob3VsZCBiZSBjb25zaWRlcmVkIHRoZSBmaW5hbCB0cnV0aDogd2hpbGUgZmFjdHMgYW5kIHNhbXBsZXMgd2VyZSB0ZXN0ZWQgSSBtaWdodCBtaXNzZWQgc29tZSBvcHRpb25zIHRoYXQgbWlnaHQgZnVydGhlciBlbmhhbmNlIHlvdXIgZXhwZXJpZW5jZS4NCg0KIyBUaGUgc29sdXRpb24NCg0KKkFzIEkgaG9wZSB5b3UgdW5kZXJzdGFuZCB0aGlzIGlzIGp1c3QgdXNlZCBmb3IgZG9jdW1lbnRpbmcgc29tZSBjcmFja2luZyBwYXNzd29yZCB0b29scyBub3QgYSByZWNvbW1lbmRhdGlvbiBmb3IgYSBiZXN0IHByYWN0aWNlOiBpbWFnaW5lIHdoYXQgY3VzdG9tZXJzIHdvdWxkIHRoaW5nIGFib3V0IHlvdXIgZXRoaWNzIGlmIHJlYWxpemluZyB3aGF0IHlvdSBoYXZlIGRvbmUuLi4qDQoNClNvLCBjb21pbmcgYmFjayB0byB0aGUgdG9waWM6IHRyeSBzb21lIGNyYWNraW5nIHRvb2xzLCBkbyBhIHJldmVyc2UgZW5naW5lZXJpbmcgb2YgcGFzc3dvcmRzIGFuZCB0aGVuIGNvbXB1dGUgdGhlIHRhcmdldCBTSEEtMjU2IGhhc2guDQoNClByb2JsZW0gc29sdmVkISBXZWxsLCBub3QgZXhhY3RseS4gSGF2aW5nIGEgdGVjaG5pY2FsIHNvbHV0aW9uIGlzIG5vdCBhbHdheXMgZXF1aXZhbGVudCB3aXRoIGhhdmluZyB0aGUgcHJvYmxlbSBhY3R1YWxseSBzb2x2ZWQsIGFzIHdlIHdpbGwgZGlzY292ZXIgc29vbi4NCg0KVG9vbHMgaW52ZXN0aWdhdGVkOg0KLSBqb2huIHRoZSByaXBwZXIgKFtodHRwOi8vd3d3Lm9wZW53YWxsLmNvbS9qb2huL10oaHR0cDovL3d3dy5vcGVud2FsbC5jb20vam9obi8pKQ0KLSBoYXNoY2F0IChbaHR0cHM6Ly9oYXNoY2F0Lm5ldC93aWtpL10oaHR0cHM6Ly9oYXNoY2F0Lm5ldC93aWtpLykpDQoNCiMjIEpvaG4NCg0KQmFzaWMgdXNhZ2UgaXMgc3RyYWlnaHQgZm9yd2FyZDoNCi0gRXhwb3J0IGhhc2hlZCBwYXNzd29yZCBpbiBhY2NlcHRlZCB0ZXh0IGZvcm1hdDogYDx1c2VybmFtZT46PGNyeXB0KDMpPmAgcGVyIGxpbmU7IHNvbWV0aGluZyBsaWtlIGBmbG9yaW46JDEkZmxvcmluJDFZMkgzVEMuS29TV1dON3Y5aFVaMC5gDQotIHJ1biBqb2huOiBgam9obiBwYXNzd29yZHMudHh0YA0KDQojIyMgU2V2ZXJhbCB2YXJpYXRpb25zDQoNCiMjIyMgU2luZ2xlIG1vZGUNCg0KUnVuIGp1c3QgcnVsZXMgZnJvbSB0aGUgY29uZmlndXJhdGlvbiBmaWxlIHNlY3Rpb24gW0xpc3QuUnVsZXM6U2luZ2xlXSAoc2VlIGpvaG4uaW5pKQ0KDQpgam9obiAtLXNpbmdsZSBwYXNzd29yZHMudHh0YA0KDQojIyMjIEluY3JlbWVudGFsDQoNCkJhc2VkIG9uIHRoZSBgSW5jcmVtZW50YWw6WFhYYCBzZWN0aW9uIGRlZmluaXRpb24gam9obiB3aWxsIHRyeSAoYnJ1dGUgZm9yY2UpIGFsbCBjb21iaW5hdGlvbnMuIFNlZSBiZWxvdyBhIGN1c3RvbWl6ZWQgTXlBbHBoYSBzZWN0aW9uOg0KDQpgYGANCltJbmNyZW1lbnRhbDpNeUFscGhhXQ0KRmlsZSA9ICRKT0hOL2FscGhhLmNocg0KTWluTGVuID0gMQ0KTWF4TGVuID0gNg0KQ2hhckNvdW50ID0gMjYNCmBgYA0KYHJlbSBqb2huIC1pPU15QWxwaGEgLi4vUGFzc3dvcmRzLnR4dGANCg0KIyMjIFJlbWFya3MNCg0KIyMjIyBUaGUgZ29vZCBuZXdzDQoNCk5vdCBzbyBnb29kIGZvciBjdXN0b21lcnMgYWN0dWFsbHk6IHRoZSBzaW5nbGUgbW9kZSB3aWxsIGJlIGFibGUgdG8gcXVpY2sgKGluIGEgbWF0dGVyIG9mIHNlY29uZHMgZm9yIHRoZSAxMDAwIHNhbXBsZXMgSSB1c2VkKSBzb2x2ZSAxMCUgb2YgdGhlIHVzZXJzIGJ5IHVzaW5nIGNvbW1vbiBwYXR0ZXJucyBhcHBsaWVkIHRvIHRoZWlyIHVzZXIgbmFtZXMuIFRoaXMgbWlnaHQgbm90IGJlIHZhbGlkIGZvciBvdGhlciBzYW1wbGVzDQoNCiMjIyMgVGhlIGJhZCBuZXdzDQoNCioqam9obioqIGlzIHNpbmdsZSB0aHJlYWRlZCwgc28gSSBoYWQgdG8gc3BsaXQgdGhlIHBhc3N3b3Jkcy50eHQgaW50byBmb3VyIGZpbGVzIGFuZCBydW4gaXQgaW4gcGFyYWxsZWwuIEFmdGVyIHNldmVyYWwgZGF5cyBqdXN0IHNvbWUgYWRkaXRpb25hbCB0ZW5zIG9mIHBhc3N3b3JkcyB3ZXJlIGRpc2NvdmVyZWQsICgxLCAyIG9yIDMgbGV0dGVycy9kaWdpdHMpIHNvIEkgY2FkIHNheSBnb29kIGJ5IHRvIHRoZSByZXN0DQoNCiMjIEhhc2hjYXQNCg0KSXQgY29tZXMgaW50byB0d28gZmxhdm91cnM6DQotIENQVSBiYXNlZCAoW2h0dHBzOi8vaGFzaGNhdC5uZXQvaGFzaGNhdC9dKGh0dHBzOi8vaGFzaGNhdC5uZXQvaGFzaGNhdC8pKQ0KLSBHUFUgYmFzZWQgKFtodHRwczovL2hhc2hjYXQubmV0L29jbGhhc2hjYXQvXShodHRwczovL2hhc2hjYXQubmV0L29jbGhhc2hjYXQvKSkNCg0KSWYgeW91IGFyZSBsdWNreSBlbm91Z2ggdG8gaGF2ZSBvbmUgb2YgdGhlIHR3byBzdXBwb3J0ZWQgR1BVJyAoQU1EIG9yIE52aWRpYSkgZ28gZm9yIHRoZSBzZWNvbmQgKHNldmVyYWwgbWFnbml0dWRlIHRpbWVzIGZhc3RlciBpbiBteSBzYW1wbGVzISkuDQoNClRoZSB1c2FnZSBsb29rZWQgbW9yZSBjb21wbGljYXRlZCB0aGFuIGZvciBqb2huIChtaWdodCB3b3J0aCB0byBleHBsb3JlIGRpcHBlcik7IHdoYXQgSSB1c2VkIHNvcnQgb2YgZXh0ZW5zaXZlbHkgd2FzIHRoZSBgbWFzayBhdHRhY2tgIChbaHR0cHM6Ly9oYXNoY2F0Lm5ldC93aWtpL2Rva3UucGhwP2lkPW1hc2tfYXR0YWNrXShodHRwczovL2hhc2hjYXQubmV0L3dpa2kvZG9rdS5waHA/aWQ9bWFza19hdHRhY2spKS4NCg0KUGFzc3dvcmQgdGV4dCBmaWxlIHNob3VsZCBjb250YWluIChwZXIgbGluZSkganVzdCB0aGUgY3RyeXB0bygzKSBwYXJ0LCBubyB1c2VyIG5hbWVzDQoNClNhbXBsZXMgKHNob3VsZCBiZSB0aGUgc2FtZSBmb3IgQ1BVIGJhc2VkIGhhc2hjYXQgKGBoYXNoY2F0LWNsaTY0LmV4ZWApKToNCmBgYA0KY3VkYUhhc2hjYXQ2NC5leGUgLS1oYXNoLXR5cGU9NTAwIC1hIDMgQ3J5cHRIYXNoZXMudHh0ID9sP2w/bD9sP2wNCmN1ZGFIYXNoY2F0NjQuZXhlIC0taGFzaC10eXBlPTUwMCAtYSAzIENyeXB0SGFzaGVzLnR4dCA/bD9sP2w/ZA0KY3VkYUhhc2hjYXQ2NC5leGUgLS1oYXNoLXR5cGU9NTAwIC1hIDMgQ3J5cHRIYXNoZXMudHh0ID9sP2w/bD9sP2QNCmN1ZGFIYXNoY2F0NjQuZXhlIC0taGFzaC10eXBlPTUwMCAtYSAzIENyeXB0SGFzaGVzLnR4dCA/bD9sP2w/bD9sP2QNCmN1ZGFIYXNoY2F0NjQuZXhlIC0taGFzaC10eXBlPTUwMCAtYSAzIENyeXB0SGFzaGVzLnR4dCA/bD9sP2w/bD9sP2w/ZA0KY3VkYUhhc2hjYXQ2NC5leGUgLS1pbmNyZW1lbnQgLS1pbmNyZW1lbnQtbWluPTQgLS1oYXNoLXR5cGU9NTAwIC1hIDMgQ3J5cHRIYXNoZXMudHh0IC0xID9sP2QgPzE/MT8xPzE/MT8xDQoNCmBgYA0KWW91IGNhbiB1c2UgdXAgdG8gNCBjdXN0b20gY2hhciBzZXQgZGVmaW5pdGlvbnMsIHNvbWV0aGluZyBsaWtlOg0KYGBgDQpjdWRhSGFzaGNhdDY0LmV4ZSAtLWhhc2gtdHlwZT01MDAgLWEgMyBDcnlwdEhhc2hlcy50eHQgLTEgP3UgLTIgP2wgLTMgP2QgPzE/Mj8yPzI/Mz8zDQpgYGANClRoaXMgd2lsbCBtZWFuIHRyeSBhbGwgY29tYmluYXRpb25zIHRoYXQgc3RhcnQgd2l0aCBhbiB1cHBlciBsZXR0ZXIsIGNvbnRhaW5zIDMgbG93ZXIgY2FzZSBsZXR0ZXJzIGFuZCBlbmRzIHVwIGludG8gdHdvIGZpZ3VyZXMuDQoNCg0KQmVzdCBndWVzczogdGhlcmUgaXMgYSB0b29sIHRoYXQgYmFzZWQgb24gbWFzayBjYW4gZ2VuZXJhdGUgd29yZCBmaWxlcyBvbiB3aGljaCB5b3UgY291bGQgcnVuIGhhc2hjYXQgYnkgYXBwbHlpbmcgcnVsZXMuIEp1c3QgcHV0dGluZyAob25jZSBhZ2FpbiwgYXMgYmVzdCBndWVzcykgdG9nZXRoZXIgd2hhdCBJIHJlbWVtYmVyIGZyb20gcmVhZGluZyBjaGFvdGljYWxseSB0aGUgZG9jdW1lbnRhdGlvbi4NCg0KIyMjIFRoZSBHb29kIE5ld3MNCg0KSWYgcGFzc3dvcmRzIGFyZSBzaG9ydCBlbm91Z2ggKDV+NiBpbiBsZW5ndGgpIGFuZCB5b3Ugd2lsbCBiZSBhYmxlIHRvIGd1ZXNzIHRoZSByaWdodCBtYXNrIHRoZSBHUFUgYmFzZWQgdmVyc2lvbiB3aWxsIG1pZ2h0IGRvIHRoZSBqb2IgKGxpa2UgMjAgaG91cnMgZm9yID9sP2w/bD9sP2wgbWFzaykuIENQVSBsb2FkIHdpbGwgYmUgbWluaW1hbC4NCg0KDQojIyMgVGhlIEJhZCBOZXdzDQpJZiB0aGUgdXNlcnMgd2VyZSBjbGV2ZXIgZW5vdWdoIHRvIHVzZSBsb25nZXIgcGFzc3dvcmRzLCBjb21iaW5hdGlvbiBvZiBVcHBlci9sb3dlci9kaWdpdHMvc3BlY2lhbCBjaGFyYWN0ZXIgc3ByZWFkIGFsbCBvdmVyIHRoZSBzdHJpbmcgeW91IGFyZSBzdHVjayBpbiBtb250aHMveWVhcnMgb2Ygd2FpdGluZw0KDQojIENvbW1vbiBSZW1hcmtzDQoNCkZvdW5kIHBhc3N3b3JkcyBhcmUgc3RvcmVkIGluIGpvaG4ucG90LCByZXNwZWN0aXZlbHkgKmhhc2hjYXQucG90DQpCb3RoIHRvb2xzIGFyZSByZS1zdGFydC1hYmxlOg0KDQotIGNvbGQgcmVzdGFydDoganVzdCByZXN0YXJ0IHRoZSBwcm9jZXNzIGFuZCBmb3VuZCBwYXNzd29yZHMgYXJlIHNraXBwZWQgKGJ1dCB0aGUgcHJvY2VzcyBpcyBzdGFydGVkIGZyb20gdGhlIGJlZ2lubmluZyBvbiBhIHNtYWxsZXIgbGlzdCBvZiBoYXNoZXMpDQotIHdhcm0gcmVzdGFydCwgYmFzZWQgb24gYSBzYXZlZCBzZXNzaW9uIHdoaWNoIHdpbGwgYWN0dWFsbHkgcmVzdGFydCB3ZXJlIGZyb20gaXQgd2FzIGludGVycnVwdGVkOg0KCS0gdGVzdGVkIHRvciBjdWRhSGFzaGNhdDogcHJvdmlkZSBhIHNlc3Npb24gbmFtZSBhdCBmaXJzdCBydW4gYW5kIHVzZSB0aGF0IHNlc3Npb24gbmFtZSBmb3IgcmVzdG9yZQ0KYGBgDQpjdWRhSGFzaGNhdDY0LmV4ZSAtLWhhc2gtdHlwZT01MDAgLWEgMyAtLXNlc3Npb249U2Vzc2lvbiBDcnlwdEhhc2hlczEwLnR4dCAgLTEgYWJjZGVmZ2hpamxtbm9wcnN0dXYgPzE/MT8xPzE/MT8xDQouLi4NCmN1ZGFIYXNoY2F0NjQuZXhlIC0tc2Vzc2lvbj1TZXNzaW9uIC0tcmVzdG9yZQ0KYGBgDQoqKkJlIGF3YXJlOioqIERvIG5vdCBxdWl0IGltbWVkaWF0ZWx5IGFmdGVyIHJlc3RhcnRpbmcgaW4gcmVzdG9yZSBtb2RlOyB3YWl0IHRpbGwgdGhlIGN1cnJlbnQgcmVzdG9yZSBwb2ludCBjaGFuZ2VzIGZyb20gemVybyB0byBzb21ldGhpbmcgbmVhciB0aGUgYWN0dWFsIHByb2dyZXNzIHZhbHVlIG90aGVyd2lzZSB5b3Ugd2lsbCBsb29zZSBhbGwgd29yayBkb25lIHNvIGZhci4gVGhpcyBpcyBub3JtYWwgYmVoYXZpb3VyIGFzIHN0YXRlZCBvbiBzb21lIGFuc3dlcnMgb24gZm9ydW0s

Monday, May 16, 2016

MySQL Linked Server from SQL Server 2014

MySQL Linked Server from SQL Server 2014

It might work from other SQL Server versions...

Install MySQL ODBC connector

  • Download and install latest x64 MySQL ODBC connector; version 5.3.6 at the moment of this post.
  • Create an x64 ODBC System DSN; suppose we named it MySQLDS

Create the Linked Server

  • Add a Linked Server
    • Name: at your will, suppose MySQLLS
    • Provider: Microsoft OLEDB Provider for ODBC Drivers
    • Product Name: MySQL
    • Data Source: MySQLDS
    • Provider String:ODBC;DSN=MySQLDS
    • Location: (empty)
    • Catalog:<name of desired catalog>
  • On Security tab:
    • Check Be made using this security context:
      • root (not really very secure)
      • <password>

Change Provider Options (Linked Servers->Providesr->MSDASQL)

  • Check Level zero only; this will allow sentences like SELECT * FROM MySQLLS...Table
IyBNeVNRTCBMaW5rZWQgU2VydmVyIGZyb20gU1FMIFNlcnZlciAyMDE0DQoNCkl0IG1pZ2h0IHdvcmsgZnJvbSBvdGhlciBTUUwgU2VydmVyIHZlcnNpb25zLi4uDQoNCiMjIEluc3RhbGwgTXlTUUwgT0RCQyBjb25uZWN0b3INCg0KKiBEb3dubG9hZCBhbmQgaW5zdGFsbCBsYXRlc3QgeDY0IE15U1FMIE9EQkMgY29ubmVjdG9yOyB2ZXJzaW9uIDUuMy42IGF0IHRoZSBtb21lbnQgb2YgdGhpcyBwb3N0Lg0KKiBDcmVhdGUgYW4geDY0IE9EQkMgU3lzdGVtIERTTjsgc3VwcG9zZSB3ZSBuYW1lZCBpdCBgTXlTUUxEU2ANCg0KIyMgQ3JlYXRlIHRoZSBMaW5rZWQgU2VydmVyDQoNCiogQWRkIGEgTGlua2VkIFNlcnZlcg0KCSogTmFtZTogYXQgeW91ciB3aWxsLCBzdXBwb3NlIGBNeVNRTExTYA0KCSogUHJvdmlkZXI6IGBNaWNyb3NvZnQgT0xFREIgUHJvdmlkZXIgZm9yIE9EQkMgRHJpdmVyc2ANCgkqIFByb2R1Y3QgTmFtZTogTXlTUUwNCgkqIERhdGEgU291cmNlOiBgTXlTUUxEU2ANCgkqIFByb3ZpZGVyIFN0cmluZzpgT0RCQztEU049TXlTUUxEU2ANCgkqIExvY2F0aW9uOiAoZW1wdHkpDQoJKiBDYXRhbG9nOmA8bmFtZSBvZiBkZXNpcmVkIGNhdGFsb2c+YA0KKiBPbiBTZWN1cml0eSB0YWI6DQoJKiBDaGVjayAqQmUgbWFkZSB1c2luZyB0aGlzIHNlY3VyaXR5IGNvbnRleHQqOg0KCQkqIGByb290YCAobm90IHJlYWxseSB2ZXJ5IHNlY3VyZSkNCgkJKiBcPHBhc3N3b3JkXD4NCg0KIyMgQ2hhbmdlIFByb3ZpZGVyIE9wdGlvbnMgKExpbmtlZCBTZXJ2ZXJzLT5Qcm92aWRlc3ItPk1TREFTUUwpDQoNCiogQ2hlY2sgYExldmVsIHplcm8gb25seWA7IHRoaXMgd2lsbCBhbGxvdyBzZW50ZW5jZXMgbGlrZSBgU0VMRUNUICogRlJPTSBNeVNRTExTLi4uVGFibGVg