3. 3
Timing attack: Java vulnerability
• Site-channel attack, implementation attack
• Attacker analyses a system reaction time for different input parameters and looks for ways to compromise the system
• CVE-2016-6210: OpenSSH uses BLOWFISH as hash for non-existing users and SHA256/SHA512 for existing. It is
exploitable with number of inputs more than 10K.
• Java bug Bug # 6863503 (Jul 2009) in java.security.MessageDigest Java 6.0 Update 15
public static boolean isEqual(byte digesta[], byte digestb[]) {
if (digesta.length != digestb.length)
return false;
for (int i = 0; i < digesta.length; i++) {
if (digesta[i] != digestb[i]) {
return false;
}
}
return true;
}
5. 5
Array comparison
Opportunities And Limits Of Remote Timing Attacks:
• WWW Remote timing difference: 20 µs per 1000 attempts.
• Lan: 100ns per 1000 attempts.
• Side-channel amplification to slow down the website
public static boolean isEqual(byte[] a, byte[] b) {
int result = 0;
result = a.length ^ b.length;
for (int i = 0; i < a.length && I < b.length; i++) {
result |= a[i] ^ b[i];
}
return result == 0;
}
Bug was fixed in Java SE 6 Update 17 (Dec 2009) “SECURITY: MessageDigest.isEqual introduces timing attack
vulnerabilities”
6. 6
Array comparison
• Constant time
result = 0
For x, y in zip(HMAC(key, msg), signature)
result |= ord(x) ^ ord(y)
return result == 0
• Double HMAC Verification
def Verify(key, msg, signature)
mac = HMAC(key, msg)
return HMAC(key, mac) == HMAC(key, signature)
7. 7
Array comparison
Keyczar has the same vulnerability in Java and Python wrappers HMAC verify function:
• src/keyczar/keys.py:
return self.Sign(msg) == sig_bytes
• src/org/keyczar/HmacKey.java:
return Arrays.equals(hmac.doFinal(), sigBytes);
Keyczar has several known security vulnerabilities
8. 8
Random numbers
Random numbers are required for:
• Application behavior:
• Numerical methods
• Games: RPG, Casino
• Create temporary password
• Cryptography: nonce, salt, IV, keys
Random number generation(RNG)
• Hardware RNG (TRNG)
• Pseudorandom RNG (PRNG or DRNG)
PRNG
• Cryptographically secure PRGN (CSPRNG)
• Next-bit test
• State compromise extensions
• Software developer predicted slots machine results (2017).
• TPM ROCA: Vulnerable RSA generation (Oct 2017)
10. 10
Usage of random numbers
Software way to full entropy pool: entropy daemon haveged. It uses timings of execution of different pieces of code.
Linux:
/dev/random blocking pseudorandom number generator. Should be used for long-lived GPG/SSL/SSH keys
/dev/urandom non-blocking pseudo number generator (from 2016 ChaCha20 algorithm in use)
Pool size
# cat /proc/sys/kernel/random/poolsize
4096
Pool value:
# cat /proc/sys/kernel/random/entropy_avail
186
# /dev/hwrng
11. 11
Usage of random numbers
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
unsigned int data = 0;
int fd = open("/dev/random", O_RDONLY);
ssize_t result = read(fd, &data, sizeof(data));
fprintf(stdout, "%u", data);
close(fd);
}
12. 12
Usage of random numbers
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
struct stat buf = {0};
const char* dev = "/dev/random";
stat(dev, &buf);
if(S_IFCHR != (buf.st_mode & S_IFMT))
{
fprintf(stdout, "%s not a character device, exit", dev);
return -1;
}
unsigned int data;
int fd = open("/dev/random", O_RDONLY | O_NOFOLLOW);
ssize_t result = read(fd, &data, sizeof(data));
fprintf(stdout, "%u", data);
close(fd);
}
13. 13
Usage of random numbers
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <linux/random.h>
int main(int argc, char **argv)
{
struct stat buf = {0};
const char* dev = "/dev/random";
stat(dev, &buf);
if(S_IFCHR != (buf.st_mode & S_IFMT))
{
fprintf(stdout, "%s not a character device, exit", dev);
return -1; }
unsigned int data;
int fd = open("/dev/random", O_RDONLY | O_NOFOLLOW);
int entropy = 0;
if(!ioctl(fd, RNDGETENTCNT, &entropy))
{
fprintf(stdout, "Failed to ioctl for RNDGETENTCNT, exit");
return -1; }
14. 14
Usage of random numbers
if (entropy < sizeof(data)) {
fprintf(stdout, "There is not enough entropy to fill the buffer, exit");
return -1;
}
while(true) {
ssize_t result = read(fd, &data, sizeof(data));
if(-1 == result)
{
if(EAGAIN == errno || EINTR == errno)
continue;
close(fd);
return -1;
}
break;
}
fprintf(stdout, "%u", data);
close(fd);
return 0;
}
15. 15
How to improve the example
• Copy all available portions of data from the device, not only the full buffer
• Check device major and minor numbers: /dev/random 1,8. /dev/urandom 1,9
• Use “fopen” family instead of “open” due to open could be interrupted, but “fopen”
takes care of it
• Check file descriptor limit before opening
• Application could be launched inside the “chroot”, so /dev will be unavailable
• Use new Linux syscall (available from kernel 3.4.17):
• int getrandom(void *buf, size_t buflen, unsigned int flags);
• Flags: GRND_RANDOM, GRND_NONBLOCK
• Calles via syscall syscall(SYS_getrandom, buf, size, flags)
• Available direct call from GNU C 2.25 (Feb 2017)
• Take a look at libsodium implementation:
https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/sysran
dom/randombytes_sysrandom.c
• Also it’s recommended to store entropy pool content to the hard drive during shutdown
and read it on startup
16. 16
Linux kernel random API
Random entropy pool defines (linux/random.h):
• RNDGETENTCNT: Get the entropy count
• RNDADDTOENTCNT: Add to (or subtract from) the entropy count (Superuser only)
• RNDGETPOOL: Get the contents of the entropy pool. (Superuser only). Deprecated
• RNDADDENTROPY: Write bytes into the entropy pool and add to the entropy count. (Superuser only)
• RNDZAPENTCNT: Clear entropy count to 0. (Superuser only.)
• RNDCLEARPOOL: Clear the entropy pool and associated counters. (Superuser only.)
17. 17
JERNG
Jitter Entropy Random Number Generator (JRNG) was introduced to Linux kernel in v 4.2 (2015)
DRBG is now seeded with both /dev/random and Jitter RNG. If kernel pool isn't ready then DRBG will be reseeded when
it is.
For Linux kernel development use kernel API get_random_bytes() (non-blocking call)
Example: who uses random numbers in kernel and who provides entropy to the entropy pool
http://www.kneuro.net/cgi-bin/lxr/http/source/include/linux/random.h
Россияне придумали «первый в мире» биологический генератор случайных чисел.
18. 18
How CloudFlare secure Interet
CloudFlare uses LavaLamp as a TRNG.
London office uses Chaotic pendulum.
Singapore office uses radio active isotope.
19. 19
CVE-2008-0166 OpenSSL
In 2008 it was founded a vulnerability in Debian OpenSSL random number generator that generates predictable
numbers.
Valgrind reports of uninitialized memory usage.
Method that adds entropy source:
static void ssleay_rand_add(const void *buf, int num, double add)
............
MD_Update(&m,buf,j)
....
Uninitialized memory was used as one of the entropy sources. But comment of MD_Update removes add entropy
sources. PID was the only one.
It was found after two years.
Brute-force attack for vulnerable SSL certificate requires only 65536 iterations (~20 min). A lot of web sites
certificates could be compromised. Most of CA reissued compromised certificates.
Exploit: https://www.exploit-db.com/exploits/5720
20. 20
Dual_EC_DRBG
Dual_EC_DRBG: Dual Elliptic Curve Deterministic Random Bit Generator is an algorithm that was presented as a
cryptographically secure pseudorandom number generator
Suspicions:
• Offered by NSA
• Very Intricate description
• Worked thousand times slower that competitors
Weakness:
• With small amount of output it’s possible to completely recover the internal state of EC-DRBG, and therefore
predict all future output (Dan Shumow and Niels Ferguson, CRYPTO 2007)
NIST make Dual_EC_DRBG a standard in 2006.
Implemented in:
• OS Windows starting from Windows Vista SP1. In Windows 7 in CNG.SYS and BCryptGenRandom. Also works in
userspace.
• RSA Security products.
NIST recalled this standard only in 2014 after Edward Snowden published NSA leaked documents.
21. 21
Intel Secure Key
Intel developed it’s own PRNG and starting from Ivy Bridge all CPUs have it.
• RDSEED: Generates seed
• RDRAND: provides pseudo number results
Implemented as AES in AES-CBC-MAC mode.
drivers/char/random.c: extract buf
for (i = 0; i < LONGS(EXTRACT_SIZE); i++)
{
unsigned long v; // arch_get_random is RDRAND.
if (!arch_get_random_long(&v)) break;
hash.l[i] ^= v;
}
Potential vulnerability is when CPU-generated random numbers could reverse existing hash and make it constant
(e.x. 0)
Also applications that use RDRAND directly are vulnerable to secret key that used for AES
22. 22
.Net System.Random Vulnerability
.Net class has System.Random class that generates random numbers based on Donald E. Knuth's subtractive
random number generator algorithm. It is described in D. E. Knuth. "The Art of Computer Programming, volume 2:
Seminumerical Algorithms". Addison-Wesley, Reading, MA, second edition, 1981.
• Instead of using Fibonacci sequence coefficient 24 and 55 a 21 and 55 are used. Due to this PRGN period is no
longer than (2^55-1).
• Default constructor seeds the current time
https://connect.microsoft.com/VisualStudio/feedback/details/634761/system-random-serious-bug (2011)
This issue hasn’t fixed yet. Even in the .Net Core 2.0 (Aug 14 2017)
System.Security.Cryptography.RNGCryptoServiceProvider should be used. Wrapper of CryptGetRandom.
23. 23
C++ example
On Linux, /dev/urandom is used
On Windows, RtlGenRandom (not CryptGenRandom to save resources for CryptoAPI) is used
libSodium example:
#include "sodium.h"
int main(int argc, char** argv)
{
unsigned char data[32];
uint32_t rnd;
//Fill array with 32 bytes not null-terminated
randombytes_buf(data, 32);
//Random number between 0 and 9
rnd = randombytes_uniform(10);
}
24. 24
Strings Security
Security problems of usage string in programming languages:
• Store unencrypted data in memory
• Non-obvious memory coping and reallocation
• Object destruction actually doesn’t clear memory data, especially important for memory-managed
languages like Java, C#.
• Strings in String Pool is immutable and every modification create new string
• Common way to work aroud the issues is to use char[]
25. 25
.Net Security string
.Net offers class SecureString
Mode data protection than String:
• Doesn’t store data as plain text in memory, on Windows encryption used. Mono doesn’t encrypt
SecureString.
• Prevents constructing from String, only add methods (character-at-a-time)
• Memory clear by Dispose method
• Supports NetworkCredential, PasswordBox , SQLConnection, X509Certificate2 , etc
26. 26
Java Security string
In SWING getPassword() returns char[]/
• Java Cryptography Architecture (JCA) Reference Guide recommends to use char[] for sensitive data
• Secure Coding Guidelines for Java SE recommends the same in other words
27. 27
C++ Strings Security
std::string, MFC String, QString don’t support security features.
Sodium API can help:
• sodium_init()
• sodium_allocarray(size_t count, size_t size): add guard pages around the protected data
to make it less likely to be accessible in a heartbleed-like scenario
• void sodium_memzero(void * const pnt, const size_t len): optimization protected,
doesn’t use memset
• int sodium_mlock(void * const addr, const size_t len): avoid swapping data to the
disk
• int sodium_mprotect_noaccess(void *ptr): makes a region allocated using sodium_malloc()
or sodium_allocarray() inaccessible.
• int sodium_mprotect_readonly(void *ptr): Attempting to modify the data will cause the
process to terminate.
• int sodium_mprotect_readwrite(void *ptr): makes memory region accessible back after
protection
28. 28
C++ Strings Security
template <typename T> struct secure_allocator : public std::allocator<T>
{
public:
template<class U> struct rebind { typedef secure_allocator<U> other; };
secure_allocator() throw() {}
secure_allocator(const secure_allocator&) throw() {}
template <class U> secure_allocator(const secure_allocator<U>&) throw() {}
void deallocate(pointer p, size_type n) {
std::fill_n((volatile char*)p, n * sizeof(T), 0);
std::allocator<T>::deallocate(p, n);
p = nullptr;
}
};
using secure_string = std::basic_string<char, std::char_traits<char>,
secure_allocator<char>>;
int main()
{
secure_string s = "Secure string";
std::cout << s << 'n';
return 0;
}
29. 29
Strings Security: EFBFBD issue
Some Android applications faced with password entropy issue: entropy seriously reduced:
Before: B7B0F88D603466CF7BF26C24E2B2AA576AAFC5E90C6BD4EECCC576B9D7F1E9C3
After:
EFBFBDEFBFBDEFBFBD603466EFBFBD7BEFBFBD6C24E2B2AA576AEFBFBDEFBFBDEFBFBD0C6BEFBFBDEF
BFBDEFBFBDEFBFBD76EFBFBDEFBFBDEFBFBDEFBFBDEFBFBD
What wrong with this code:
privateString generateRandomPassword() {
byte[] arr = newbyte[42];
newSecureRandom().nextBytes(arr);
return new String(arr);
}
30. 30
Strings Security: EFBFBD issue
Android platform default charset is always UTF-8.
In UTF-8, the hex string “EFBFBD” represents a replacement character, i.e character whose value is
unknown or un-representable. Every unknown char is replaced by the “EFBFBD” sequence.
Bytes conversion for different OS:
• Windows 7 (windows-1252, not unicode)
B7B0F88D603466CF7BF26C24E2B2AA576AAFC5E90C6BD4EECCC576B9D7F1E9C3
B7B0F83F603466CF7BF26C24E2B2AA576AAFC5E90C6BD4EECCC576B9D7F1E9C3
For windows-1252 values 81, 8D, 8F, 90, 9D are unused and replaced by 3F (?)
• Ubuntu 12.04:
EFBFBDEFBFBDEFBFBDEFBFBD603466EFBFBD7BEFBFBD6C24E2B2AA576AEFBFBDEFBFBDEFBFBD0C6BEFB
FBDEFBFBDEFBFBDEFBFBD76EFBFBDEFBFBDEFBFBDEFBFBDEFBFBD
31. 31
Strings Security: EFBFBD issue
How to fix the issue:
• Avoid bytes to String conversion. See “How to Use Password Fields” from “The Java™ Tutorials” for
details
• Use base64 encoding:
• private String generateRandomPassword() {
byte[] arr = newbyte[42];
return Base64.encodeToString(arr, 0);
}