Tomas' Labroratory

Adventures with TeslaCrypt (AKA “VVV Virus”)

I received an urgent call from a client.  The client’s computer got hit by the VVV virus AKA TeslaCrypt. All of their files were renamed to .vvv and when trying to open them, a message said that the only way to get them back was to pay $500 USD before a specific date, or $1000 USD after.  The payment had to be in bitcoins.  First question I asked: "Do you have a backup?" Client said “No”.  Having read up about ransomware like CryptoLocker, I knew this was  bad news.  Normally once the files are encrypted, it’s game over.   Only way out is backup.  Nevertheless, I dove into researching a possible solution – just in case. There were 4 possible methods that I tried:

Running out of time, and faced with the slim chance of recovery, my client felt he had no choice other than to pay the ransom.   The criminals are running  an organized business, and this gives it the impression that they may actually deliver the decryption key after payment in order to preserve their reputation.   After all, if people have bad experience after sending a payment, the word will spread and no one will ever send them any money no matter how desperate they are.  On the other hand if the payment and decryption are very quick and easy, people will see it as an easy way out. This, combined with how easy it is for the criminal to give out the decryption key (just a single click of a button) it is in the criminal’s best interest to deliver the decryption key promptly.  All signs pointed to a well organized setup.  The criminals even have even had  a working web support and billing system where you can get answers to your questions regarding on how to submit your Bitcoin payment.  The response time to a general question ended up being about 4 hours – which is not bad.   Actually better than support at many large enterprises.  Still, there are so many things that could go wrong.  Maybe the criminals are just plain evil and see this as a onetime money grab.  Maybe they could not care less about their reputation.  Maybe the criminals get shut down just before having the chance to send you the key.  Maybe the criminals screw up and lose the key, so even though they might have wanted to give it to you, they simply don’t have it.  Maybe the criminals are stupid and don't use business sense for deciding how to behave.  You are doomed if you send payment, and you are doomed if you don’t.  I was glad that it wasn’t me in this situation.  I would have no idea what to do next. My client on the other hand had to make that decision – and quickly.  He decided to pay.  Trouble was that the only accepted method of payment was through bit Bitcoin (BTC).  Because he did not have $500 USD in BTC, he had to buy Bitcoins first.  Even though it’s becoming easier and easier to buy Bitcoin, it’s still quite a process.  You either have to go through 2-5 day verification process or you have to fully trust the Bitcoin vendor.   Neither of those options was good because we were running out of time  and we were not in the mood to blindly “trust people”.  In the end we were lucky because now there is a Bitcoin ATM at Café Blanca in downtown Calgary.  There you can buy and sell Bitcoins with cash instantly.  You insert cash and the bitcoins appear in your Bitcoin wallet 2 seconds later. My client ended up gradually putting in about $700 CAD in cash to purchase 1.1 Bitcoins which the criminals demanded in order to cover the $500 USD fee.  With 1.1 bitcoins ready, we went back to the criminal’s web payment portal.  Just as we were reading the payment instructions for the 3rd time to be extra sure there is no mistake, we noticed that the criminals raised the cost to 1.25 bitcoins.  We had to top up the bitcoin wallet and proceeded to make the payment.  We sent the payment and included the transaction ID which proved receipt by the criminals.  Then we waited.  10 minutes, nothing.   1 Hour – nothing.  5 Hours – nothing.  1 day – nothing.  That was it.  The criminals got the money and we’ll never the key.  The files were still encrypted and useless. During all the waiting, I resumed trying my hand at decryption.  To my amazement teslacrack.py method actually worked.  Not only it worked, but once I figured out the right tools and the right steps,  the actual computation time to crack the key was only 30 seconds.  This was amazing because normally these methods take weeks if you are extremely lucky.   It turns out that in addition to a mountain worth of luck on my side, the criminals made a mistake in the way they encrypted the files.  If the criminals didn’t make that mistake, no amount of luck would have helped.   Cracking  the key would take millions of years.  It is also interesting to note that the criminals encrypted different sets of files using 2 different keys meaning that even if they let  you decrypt one set of files, the other set of files would still be encrypted (presumably to force you to pay an additional fee).   Furthermore the key for one set of files was cracked in 30 seconds, the second key took more than 5 days with no success.  Luckily, the first set contained the critical files, and the client was not too concerned about the second set, so we stopped there.  By the way, eventually the link that took us to the criminal's billing/support site went blank.  We're never going to see that key or the $700+ CAD.

Lessons reinforced:

How to recover:

Step 1) Take backup and work from the backup

Step 2) Install programs:

Step 3) Identify the AES key that you will try to crack

Cannot decrypt ./IMG_1111.JPG.vvv, unknown key
 
 Software has encountered the following unknown AES keys, please crack them first using msieve: 
 
 346FA15D6F7106A05553587E67AD068EBF0CE65C9ECBA74BAE144661AB502CEFFEBCFA9FBB3CDFD9E4043B3402F970051E55063D96C94AB66B443A0F9D088A23 found in ./IMG_1111.JPG.vvv 
 
 Alternatively, you can crack the following Bitcoin key(s) using msieve, and use them with TeslaDecoder: 
 
 E82E090D9A73DC4E93201BC56394544493EFD0DD2631F588C4083F006C1CD419F096F1D6E646AA0DE8D0230CB18D009B231DEA6EF7CAFED03C6C53830E51074A found in ./IMG_1111.JPG.vvv

Step 4) Crack the AES key

Run msieve with the AES key found in step 3 (notice 0x in front):

msieve -v -e 0x346FA15D6F7106A05553587E67AD068EBF0CE65C9ECBA74BAE144661AB502CEFFEBCFA9FBB3CDFD9E4043B3402F970051E55063D96C94AB66B443A0F9D088A23

You should see something like this

random seeds: 4e305a00 6fb1837c
 
 factoring 2746299090781689070444389534863512001481868057180589068197106350690661
 
 98749363149686207988485815608295042086154388677331498764717631003373547132362899
 
 7155 (154 digits)
 
 searching for 15-digit factors
 
 P-1 stage 1 factor found
 
 searching for 20-digit factors
 
 P-1 stage 2 factor found
 
 searching for 25-digit factors
 
 P-1 stage 2 factor found
 
 commencing quadratic sieve (33-digit input)
 
 using multiplier of 3
 
 using VC8 32kb sieve core
 
 sieve interval: 4 blocks of size 32768
 
 processing polynomials in batches of 51
 
 using a sieve bound of 4909 (341 primes)
 
 using large prime bound of 196360 (17 bits)
 
 polynomial 'A' values have 4 factors
 
 
 
 sieving in progress (press Ctrl-C to pause)
 
 696 relations (302 full + 394 combined from 2196 partial), need 437
 
 696 relations (302 full + 394 combined from 2196 partial), need 437
 
 sieving complete, commencing postprocessing
 
 begin with 2498 relations
 
 reduce to 1007 relations in 2 passes
 
 attempting to read 1007 relations
 
 recovered 1007 relations
 
 recovered 24 polynomials
 
 attempting to build 696 cycles
 
 found 696 cycles in 1 passes
 
 distribution of cycle lengths:
 
    length 1 : 302
 
    length 2 : 394
 
 largest cycle: 2 relations
 
 matrix is 341 x 696 (0.1 MB) with weight 11065 (15.90/col)
 
 sparse part has weight 11065 (15.90/col)
 
 filtering completed in 1 passes
 
 matrix is 341 x 405 (0.0 MB) with weight 5168 (12.76/col)
 
 sparse part has weight 5168 (12.76/col)
 
 commencing Lanczos iteration
 
 memory use: 0.0 MB
 
 lanczos halted after 7 iterations (dim = 330)
 
 recovered 63 nontrivial dependencies
 
 commencing quadratic sieve (69-digit input)
 
 using multiplier of 23
 
 using VC8 32kb sieve core
 
 sieve interval: 12 blocks of size 32768
 
 processing polynomials in batches of 17
 
 using a sieve bound of 209771 (9278 primes)
 
 using large prime bound of 19508703 (24 bits)
 
 using trial factoring cutoff of 24 bits
 
 polynomial 'A' values have 9 factors
 
 
 
 sieving in progress (press Ctrl-C to pause)
 
 9427 relations (4473 full + 4954 combined from 52519 partial), need 9374
 
 9427 relations (4473 full + 4954 combined from 52519 partial), need 9374
 
 sieving complete, commencing postprocessing
 
 begin with 56992 relations
 
 reduce to 13757 relations in 2 passes
 
 attempting to read 13757 relations
 
 recovered 13757 relations
 
 recovered 11859 polynomials
 
 attempting to build 9427 cycles
 
 found 9427 cycles in 1 passes
 
 distribution of cycle lengths:
 
    length 1 : 4473
 
    length 2 : 4954
 
 largest cycle: 2 relations
 
 matrix is 9278 x 9427 (1.3 MB) with weight 274633 (29.13/col)
 
 sparse part has weight 274633 (29.13/col)
 
 filtering completed in 3 passes
 
 matrix is 8448 x 8512 (1.2 MB) with weight 244661 (28.74/col)
 
 sparse part has weight 244661 (28.74/col)
 
 commencing Lanczos iteration
 
 memory use: 1.2 MB
 
 lanczos halted after 135 iterations (dim = 8443)
 
 recovered 61 nontrivial dependencies
 
 p1 factor: 3
 
 p1 factor: 5
 
 p6 factor: 418819
 
 p8 factor: 10304417
 
 prp13 factor: 8162073202471
 
 prp14 factor: 84794311049579
 
 prp19 factor: 3135407003350317697
 
 prp25 factor: 2560807722929541167424011
 
 prp26 factor: 19683723106610479028057093
 
 prp45 factor: 387847886921773814156469727175786645600806381
 
 elapsed time 00:00:37 
 
 

Depending how lucky you are, this process will run for anywhere from minutes to weeks.

Step 5)  Unfactor based on prime factors from step 4

unfactor-ecdsa.py ./IMG_1111.JPG.vvv 3 5 418819 10304417 8162073202471 84794311049579 3135407003350317697 2560807722929541167424011 19683723106610479028057093 387847886921773814156469727175786645600806381
 
 Found AES private key: b'\x6d\xb8\x64\x76\x72\x31\xc4\xff\xfc\x22\x48\x20\xa5\xbc\xcd\x6c\x4c\x30\x2f\xc3\x4d\xd6\xfa\x23\x4b\x4b\x9e\x0c\x1d\xaf\xec\x07' (6DB864767231C4FFFC224820A5BCCD6C4C302FC34DD6FA234B4B9E0C1DAFEC07)

Step 6) Use AES private key to decrypt all your files

Step 7) Backup, backup, backup.  Next time this will NOT work.