# lab_Pseudo_Random_Number
###### tags: `linux`, `random number`
## Environment
```
x86_64 Ubuntu 20.04.5 LTS
```
```
x86_64 Ubuntu 16.04.7
```
</br>
</br>
</br>
## TASK 1: Generate Encryption Key in a Wrong Way
```c=
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define KEYSIZE 16
int main()
{
int i;
char key[KEYSIZE];
printf("%lld\n", (long long) time(NULL));
srand (time(NULL));
for (i = 0; i < KEYSIZE; i++){
key[i] = rand() % 256;
printf("%.2x", (unsigned char)key[i]);
}
printf("\n");
return 0;
}
```
```
# result
1665937533
c066f685a89a03e3ee38701c026b7f4
# result 2
1665937533
ac066f685a89a03e3ee38701c026b7f4
# result 3
1665937534
116284de93498bd7a041fd0fef3a1dcc
```
At first glance, we can notice that the `result 1` and `result 2` was the very same. So we can assume that it is caused by the fact that they were executed in "same" time.
Accroding to the man page:
> The srand() function sets its argument as the seed for a new sequence of pseudo-random integers to be returned by rand(). These sequences are repeatable by calling srand() with the same seed value
> [name=man page]
we can know that the purpose of line:13 `srand(time(NULL))` is to use time as the seed of `rand()` function.
</br>
</br>
## Task 2: Guessing the Key
1. Calculate the date.
```bash
❯ date -d '2018-04-18 23:08:49' +%s # the date i used in code
1524034800
❯ date -d '2018-04-17 23:08:49' +%s # the date in pdf
1523977729
❯ date -d "2018-04-15 15:00:00" +%s
1523775600
```
:::warning
Note:
Because the time zone difference between me and the where the pdf comes from, I use '2018-04-18' instead of '2018-04-17' in the pdf
:::
</br>
2. Install openssl package
```bash
sudo apt install libssl-dev
```
</br>
3. Decrypt the cipher with AES CBC 128bits
```c
void decrypt(unsigned char *cipher, unsigned char *key, unsigned char *iv, unsigned char *result)
{
AES_KEY ctx;
unsigned char tmp_iv[16] = {0};
memcpy(tmp_iv, iv, 16);
AES_set_decrypt_key(key, 128, &ctx);
AES_cbc_encrypt(cipher, result, 16, &ctx, tmp_iv, AES_DECRYPT);
}
```
4. Try generate the key in all possible time, then choose the right one
```c
for (unsigned long seed = TIME_LOWER_LIMIT; seed <= TIME_UPPER_LIMIT; seed++) {
gen_key(seed, key); // from task1.c
unsigned char tmp_plain[16] = {0};
decrypt(cipher, key, iv, tmp_plain);
if (memcmp(plain, tmp_plain, DATA_SIZE) == 0) {
print_hex(key, KEYSIZE);
return 0;
}
}
```
</br>
</br>
## Task 3: Measure the Entropy of Kernel
```bash
$ watch -n .1 cat /proc/sys/kernel/random/entropy_avail
```
I use a VM to emulate early version of linux to lab this secion, because the latter version of linux changed this "harvest hardware randomness" feature.
### In Ubuntu-16 / kernel version: 4.15.0-112-generic
while moveing mouse around: 2890 ~ 3017
while opening firfox: 3540
while creating a large file: 3840
> btw the "create a large file" experience broke my VM
> 
> I used the `yes > a` command to create large file
Then I notice that the entropy will decrease overtime.
### After 5.10.119
After linux 5.10.119 the value of `/proc/sys/kernel/random/entropy)avail` is always 256. It's not a bug, it's a new feature to the new version of linux kernel.
### Disscuss
input_pool.entropy_count
</br>
</br>
## Task 4: Get Pseudo Random Numbers from /dev/random

blocking
:::warning
**Question:**
> If a server uses `/dev/random` to generate the random session key with a client. Please describe how you can launch a DOS attack on such a server.
You can try to request a lot of secure connection, to force the server to generate a lot of keys and run out server's entropy pool
:::
### After linux 5.10
`/dev/random` and `/dev/urandom` almost same
==todo==
</br>
</br>
## Task 5: Get Random Numbers from /dev/urandom

unblock
> [ent man from ubuntu](https://manpages.ubuntu.com/manpages/xenial/man1/ent.1.html)
