• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Breaking AES-256 Encryption

samhain

CD-диск
Пользователь
Регистрация
02.11.2021
Сообщения
13
Реакции
59
This article fits in: Techniques for countering security software.

Really? AES-256 can not be brute forced and that is a fact and security products use it all the time. But look what happens when I run this small POC to crypt and then try to brute force a secret message
crypted with AES-256:


Original message is = My Secret Message!
Random password generated to encrypt the message = UWVVSGDADGSZIEXUGAGXXUKDYVHTDETP
Crypted message using AES-256 = mKOfC5GktNPVmR2kf/kfOGOVrG3bk9xsNqn+BjsF9r8=

Press any key to start brute forcing...

Testing password = MYJFWQBCUHVJQERMZCRSWOYFXNFIZZIQ
Testing password = YRRAKUPPRYCPYRZVOLQISHUWUWJSSEZJ
Testing password = KJZUYXDCOOJVGDHFDVPYPBQNSFNCLJPD
Testing password = XCGPNASPLEQAOQPPSFPOLVLEPOQMEOFW
Testing password = JUOJBDGCHVXGWCXZHPOEIOHVNYUWXTWP
Testing password = WMWDPHUPELEMFPEIWZNUEICMKHYGPYMI
Testing password = IFEYDKJCBCKRNBMSLJNKBBYDIQBQIDDB
Testing password = VXMSSNXPYSRXVOUCBTMAXVUUFZFABITU
Testing password = HPUNGQLCUIYDDACMQDLQUPPLCJIJUOJN
Testing password = TIBHUUAPRZFILNKVFNKGRILCASMTNTAH
Testing password = GAJCIXOCOPMOTZRFUWKWNCGSXBQDFYQA
Testing password = STRWXACPLGTUBLZPJGJMKWCJVLTNYDHT
Testing password = FLZRLERCIWZAJYHZYQICGPYASUXXRIXM
Testing password = RDHLZHFPEMGFSKPJNAISDJTRQDBHKNNF
Testing password = DWOGNKTCBDNLAXXSCKHHZCPINMERDSEY
Testing password = QOWACNIPYTURIJECRUGXWWKZLWIBWXUS
Testing password = CGEUQRWCVKBWQWMMGEGNSQGQIFMLOCLL
Testing password = PZMPEULPSAICYIUWVOFDPJCHFOPUHHBE
Testing password = BRUJTXZBOROIGVCFKXETLDXYDYTEAMRX

...many tests omitted to save space...

Testing password = TBMIFPOOSZEJTCQXCAVBRYYMAIITYCND
Testing password = GTUCTTCBPQLPBPXHRKUROSUDXRMDRHDW
Testing password = SLCXHWQOMGSUJBFRGUUHKLPTVAPNKMUP
Testing password = FEKRWZFBJXZARONBVETXHFLKSKTXDRKI
Testing password = RWSLKCTOGNGGAAVLKOSMDZHBQTXHVWBC
Testing password = DOZGYGHBCDNLINDUZXSCASCSNCAROBRV
Testing password = QHHAMJWOZUTRQZKEOHRSWMYJLLEAHGHO
Testing password = CZPVBMKBWKAXYMSODRQITGUAIVIKALYH
Testing password = PSXPPPZOTBHDGYAYSBPYPZPRGELUTQOA
Testing password = BKFKDTNBPROIOLIHHLPOMTLIDNPELVFT
Testing password = OCNERWBOMIVOWXQRWVOEJMGZAXSOEAVM
Testing password = AVUZGZQBJYCUEKXBMFNUFGCQYGWYXFLG
Testing password = MNCTUDEOGOIZNWFLBPNKCAYHVPAIQKCZ
Testing password = ZFKOIGSBDFPFVJNUQZMAYTTYTYDSJPSS
Testing password = LYSIXJHOZVWLDVVEFILQVNPOQIHCCUJL
Testing password = YQACLMVAWMDQLIDOUSLGRHKFORLLUAZE
Testing password = KJHXZQJNTCKWTUKYJCKWOAGWLAOVNFPX
Testing password = WBPRNTYAQSRCBHSHYMJMKUCNJKSFGKGR
Testing password = JTXMCWMNNJXIJTARNWICHNXEGTWPZPWK
Testing password = VMFGQAAAJZENSFIBCGIRDHTVDCZZSUND
Testing password = IENBEDPNGQLTASQLRQHHABOMBLDJKZDW
Testing password = UWVVSGDADGSZIEXUGAGXXUKDYVHTDETP

Random password initially generated = UWVVSGDADGSZIEXUGAGXXUKDYVHTDETP
Match found in 00:00:00.3239570 seconds. The password is = UWVVSGDADGSZIEXUGAGXXUKDYVHTDETP

The original message is = My Secret Message!
The brute forced message is = My Secret Message!

Press any key to close...

Took less than one second to brute force AES-256. If you want to know why, keep reading...

Let's first examine the facts. What would it take to brute force AES-256. To brute force it, you need to check 2^255 keys which would represent half of the possible combinations in a 256bit password. By checking that
amount of keys you would be covering half of the possibilities and therefore you would have a chance of 50% to guess the right password. A high-end PC can check 2^26 passwords per second. A year contains 31,557,600
seconds. In a year you would be able to test 2,117.8 trillion keys. By dividing 2^255/2,117.8 trillion you get how many years are needed to brute force AES-256, and its
27,337,893,038,406,611,194,430,009,974,922,940,323,611,067,429,756,962,487,493,203 years which is the same as 27 trillion trillion trillion trillion trillion years. If you have access to more computing power then
calculations are different but lead to the same conclusion:

Computing power Average time to crack using exhaustive search

High-end PC 27,337,893,038,406,611,194,430,009,974,922,940,323,611,067,429,756,962,487,493,203 years.
27 trillion trillion trillion trillion trillion years

Fastest supercomputer 27,337,893,038,406,611,194,430,009,974,922,940,323,611,067,429,756,962,487 years.
27,337,893 trillion trillion trillion trillion years

2 billion high-end PCs 13,668,946,519,203,305,597,215,004,987,461,470,161,805,533,714,878,481 years
13,689 trillion trillion trillion trillion years

Age of the universe 15,000,000,000 years
15 billion years

As you can corroborate in the table, its simply not possible. So then how come I did it? If you look at the code (look at end of the article), I am using standard Microsoft Libraries. So what went wrong?
The answer is, I purposely created a poor implementation of AES-256. You would be surprise on how many times security products have flaws in their implementation of these libraries.
On purpose, I used a weak random password generator. The password generator only produces uppercase letters, so instead of having to check 2^255 keys, I only have to check 2^26 possible keys. If I add
lowercase letters then it would be 2^52 keys and if I add numbers still I would be in the range of 2^62 keys. A proper password would have to be created in such a way that all of the 32 bytes could have their
full range of possible values and this of course includes non printable characters. However, in many situations, developers chose to allow only printable characters for their passwords because its easy for the
costumer to type them when requested. If you check on public implementations of AES-256, you won't see much of a difference in a large number of the instances, in regard to the errors I have shown here.
But there is even more to this story, if you run the POC you will notice that it only checks a fraction of the 2^26 possible keys. This means there is a second flaw in the algorithm, one that is worst than
the first one. The random password is also not really random although, again, uses Random Class provided by Microsoft. The problem on using this is that Random Class also is not adequate for the purpose
of creating passwords suitable to be used by AES-256 because the Random Class is seeded using the PC Clock, and the PC clock is predictable. What I have done is simply test every possible seed value
from the PC Clock moving backwards. The clock can only go one way and its forward, so by moving the clock value backward one unit at a time and knowing that Random results are always the same if the seed is the same
then I can guess the password even faster.

Lets see the code:

Код:
using System;
using System.Diagnostics;
using System.Text;

namespace BreakAES256
{
    class Program
    {
        public static string Secret = "My Secret Message!"; // Secret message to be crypted and later brute forced
        static void Main()
        {
            var randomPassword = RandomStringGenerator.RandomString(32, Environment.TickCount); // Get a random string and use the PC clock as seed to introduce the flaw
            Console.WriteLine("Original message is = " + Secret);
            Console.WriteLine("Random password generated to encrypt the message = " + randomPassword);
            var crypted = AesCryptoService.Encrypt(Secret, Encoding.ASCII.GetBytes(randomPassword), new byte[]{1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 }); // Crypt the message
            Console.WriteLine("Crypted message using AES-256 = " + Convert.ToBase64String(crypted) + "\r\n\r\n" + "Press any key to start brute forcing..."); // Show the crypted message
            Console.ReadKey();
            Stopwatch watch = new Stopwatch(); // Measure how long will it take to brute force
            watch.Start();
            for (int i = Environment.TickCount; i > 0; i--) // Check the PC clock in a backward fashion 
            {
                var randomPassword1 = RandomStringGenerator.RandomString(32, i); // Get a password to test
                var decrypted = AesCryptoService.Decrypt(crypted, Encoding.ASCII.GetBytes(randomPassword1), new byte[]{1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4 }); // Try to decode the password
                Console.WriteLine("Testing password = " + randomPassword1); // Print password being tested
                if (decrypted == Secret) // Check if we got a match
                {
                    watch.Stop(); // Stop the clock - a match was found
                    Console.WriteLine("\r\nRandom password initially generated = " + randomPassword); // Show results
                    Console.WriteLine($"Match found in {watch.Elapsed} seconds. The password is = " + randomPassword1);
                    Console.WriteLine("\r\nThe original message is = " + Secret);
                    Console.WriteLine("The brute forced message is = " + decrypted);
                    Console.WriteLine("\r\nPress any key to close...");
                    Console.ReadKey();
                    return;
                }
            }
            Console.WriteLine("No Match found...");
            Console.ReadKey();
        }
    }
}

Unsafe password generator:

Код:
using System;
using System.Text;

namespace BreakAES256
{
    internal class RandomStringGenerator
    {
        public static string RandomString(int size, int seed, bool lowerCase = false)
        {
            var random = new Random(seed); // We seed it with the PC clock on purpose
            var builder = new StringBuilder(size);
            var offset = lowerCase ? 'a' : 'A';
            const int lettersOffset = 26; // Only 26 possible letters
            for (var i = 0; i < size; i++)
            {
                var @char = (char)random.Next(offset, offset + lettersOffset);
                builder.Append(@char);
            }
            return lowerCase ? builder.ToString().ToLower() : builder.ToString();
        }
    }
}

Finally, another aspect to keep the algorithm strong is to use a different or even random nonce (iv) for each communication. In this way the attacker has to calculate the password and also the nonce for every key check.
If the password is not long enough, it can be hashed to reach a safe length, in fact, the password is more strong if you add two additional characters than if you triplicate the number of possible values of each one of
the existing characters.
In conclusion, AES-256 is safe if implemented right. There are several sources of errors during its implementation that can be exploited in certain situations to the advantage on an attacker, specially in relation to the
proper selection of a secure password but not only limited to it.

Source code attached.
 

Вложения

  • BreakingAES256.zip
    5.4 КБ · Просмотры: 50
this was interesting to read but surely this relies on multiple design faliures in the program and not AES, as you pointed out RNG seeding, only uppercase printable charecters for key etc are not flaws or limitations in the AES algorithm but poor design choices by the people that are choosing to use Random or similar for key generation (even says on the documentation page for c# Random that its insecure for key generation).

Which makes it less of a flaw in AES-256 surely and more of a lack of knowledge/caring about the impacts of insecure RNG.
if you use a predictable seed for any encryption then someone can say they have "broken" all encryption, but really its just poorly build software not encryption flaw.

Please correct if i missunderstand :)
 
Чувак, отформатируй текст, а то похоже на какой-то копи паст ей богу.
 
Чувак, отформатируй текст, а то похоже на какой-то копи паст ей богу.
yes, sorry, by creating the code in notepad++ and moving it to the forum the formatting got all wrong. Unfortunately I don't have edition privilege on my posts except for few minutes after posting them and when I realized about the problem it was already too late to correct it.
 
Вещь полезная, однако не новая, AES давно признан устойчивой криптосистемой при использовании 10-12-14 раундов шифрования. Соответственно атаки на устойчивую криптосистему путем понижения криптостойкости обречены на провал, поэтому активно используюся атаки на ключ. В данном случае почти классическая ошибка слабой генерации псевдослучайных ключей. Используйте библиотеку openssl если вы хотите что-либо шифровать и будет вам счастье, если не изменяет память она содержит более 100 проверок на случайность значений.
 
this was interesting to read but surely this relies on multiple design faliures in the program and not AES, as you pointed out RNG seeding, only uppercase printable charecters for key etc are not flaws or limitations in the AES algorithm but poor design choices by the people that are choosing to use Random or similar for key generation (even says on the documentation page for c# Random that its insecure for key generation).

Which makes it less of a flaw in AES-256 surely and more of a lack of knowledge/caring about the impacts of insecure RNG.
if you use a predictable seed for any encryption then someone can say they have "broken" all encryption, but really its just poorly build software not encryption flaw.

Please correct if i missunderstand :)
You are correct a PRNG should be used always and libraries version checked because by having access to the PC and on certain library versions there are weaknesses that can still lead to the password. Thanks for your comment.
Вещь полезная, однако не новая, AES давно признан устойчивой криптосистемой при использовании 10-12-14 раундов шифрования. Соответственно атаки на устойчивую криптосистему путем понижения криптостойкости обречены на провал, поэтому активно используюся атаки на ключ. В данном случае почти классическая ошибка слабой генерации псевдослучайных ключей. Используйте библиотеку openssl если вы хотите что-либо шифровать и будет вам счастье, если не изменяет память она содержит более 100 проверок на случайность значений.
Very pertinent comment. Thanks for pointing it out.
 
AES-256 совершенно точно криптоустойчив, однако в статье речь идет не о взломе алгоритма, а именно об использовании довольно слабой энтропии. Поэтому заголовок статьи не подходит сути.

В качестве энтропии используется время в миллисекундах, и соответственно поиск пароля идет от текущего времени перебором назад.
Чтобы перевести используемую энтропию в "биты", сделаем следующее:

log2(1000*60*60*24*1) = 26.36 (для 24 часов)
log2(1000*60*60*24*7) = 29.17 (для 7 суток)
log2(1000*60*60*24*365) = 34.87 (для года)
log2(1000*60*60*24*365*10) = 38.19 (для 10 лет)
log2(1000*60*60*24*365*100) = 41.52 (для 100 лет)

Таким образом, если пароль был сгенерирован в течение последних суток, то использованная энтропия всего 26 бит, если в течение последнего года - тогда 34-35 бит, если в течение последних 10 лет - то 38 бит, и наконец если в последние 100 лет - то 41 бит.

То есть, ни о какой 256 битной случайности тут и нет речи. Максимум 41 бит (100 лет взято с запасом).

Вот и получается что со скоростью 2^26 в секунду (та скорость, которая приводится автором как возможная) находится пароль сгенерированный в последние 24 часа. Для пароля сгенерированного в последние 7 суток, нужно всего 8 секунд, а для пароля сгенерированного в течение последнего года - нужно 365 секунд (6 минут), и наконец на пароль сгенерированный в последние 100 лет нужно 47 тыс секунд или 13 часов. [для 100 лет: из 41.52 вычитаем 26, получаем 15.52, и в этоу степень возвдим 2 - получаем 47 тыс секунд]
 
You are correct a PRNG should be used always and libraries version checked because by having access to the PC and on certain library versions there are weaknesses that can still lead to the password. Thanks for your comment.

Very pertinent comment. Thanks for pointing it out.
Thanks and would be interesting to see if you could intentionally load an insecure version of the same library and example would be an application requiring openssl libraries, but due to poor practice the DLL is loaded directly from the working directory, now would there any possible way that using an outdated/insecure version of the DLL would that possibly lead to an exploitable/insecure crypto implementation
 
AES-256 совершенно точно криптоустойчив, однако в статье речь идет не о взломе алгоритма, а именно об использовании довольно слабой энтропии. Поэтому заголовок статьи не подходит сути.

В качестве энтропии используется время в миллисекундах, и соответственно поиск пароля идет от текущего времени перебором назад.
Чтобы перевести используемую энтропию в "биты", сделаем следующее:

log2(1000*60*60*24*1) = 26.36 (для 24 часов)
log2(1000*60*60*24*7) = 29.17 (для 7 суток)
log2(1000*60*60*24*365) = 34.87 (для года)
log2(1000*60*60*24*365*10) = 38.19 (для 10 лет)
log2(1000*60*60*24*365*100) = 41.52 (для 100 лет)

Таким образом, если пароль был сгенерирован в течение последних суток, то использованная энтропия всего 26 бит, если в течение последнего года - тогда 34-35 бит, если в течение последних 10 лет - то 38 бит, и наконец если в последние 100 лет - то 41 бит.

То есть, ни о какой 256 битной случайности тут и нет речи. Максимум 41 бит (100 лет взято с запасом).

Вот и получается что со скоростью 2^26 в секунду (та скорость, которая приводится автором как возможная) находится пароль сгенерированный в последние 24 часа. Для пароля сгенерированного в последние 7 суток, нужно всего 8 секунд, а для пароля сгенерированного в течение последнего года - нужно 365 секунд (6 минут), и наконец на пароль сгенерированный в последние 100 лет нужно 47 тыс секунд или 13 часов. [для 100 лет: из 41.52 вычитаем 26, получаем 15.52, и в этоу степень возвдим 2 - получаем 47 тыс секунд]
yes you are correct in everything, AES-256 is brute force resistance. And for each scenario there is a different response. For instance, there is the scenario where the user correctly uses all the possible range of values for each character so now possibilities are much higher, he still uses the Random Class but then after crypting the message he turns off the PC. Then you have to make more calculations; and this is just one of the possible variations that we could talk about and modify the code to make it work in such instances. Perhaps for a future article. Thanks for your comment and calculations.
Thanks and would be interesting to see if you could intentionally load an insecure version of the same library and example would be an application requiring openssl libraries, but due to poor practice the DLL is loaded directly from the working directory, now would there any possible way that using an outdated/insecure version of the DLL would that possibly lead to an exploitable/insecure crypto implementation
Absolutely, yes, and since you are relying on a dll, there is also the possibility to add code to a dll to sniff the password, just to mention another route to get to the same goal. There are many security products that won't handle/dispose the password securely and are susceptible to this attack too. Thanks for commenting.
 
Чувак, отформатируй текст, а то похоже на какой-то копи паст ей богу.
Есть возможность перевести с эльфийского?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
следующий конкурс походу по переводу будет 👍
Тогда можно не открывать конкурс а банк сразу передавать Яшечке, ибо это победа определенно.
Яша - низкий поклон и уважение тебе.
 
mmh good post but how get secret key if you know the encrypted text and the original text ?
If you know both then you can brute-force the password provided the number of possible passwords is not high enough to make it unfeasible. You grab the original text and procress it using different passwords systematically until you obtain the encrypted text that matches the original algorithm. Normally this is not possible because the number of possibilities for the password is too high to make it practical. Thanks for your comment.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
If you know both then you can brute-force the password provided the number of possible passwords is not high enough to make it unfeasible. You grab the original text and procress it using different passwords systematically until you obtain the encrypted text that matches the original algorithm. Normally this is not possible because the number of possibilities for the password is too high to make it practical. Thanks for your comment.
samhain
пожалуйста, как с вами связаться
Вы в Тоx/Телеграме?
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх