# CNS HW3 > [name=B11705054游至捷] ## 1. ### (a) Grey-box fuzzing (or AFL here) create new inputs by mutation or combination of slicing of both new and old. It starts with selecting seeds, executing and gathering information. Then it analyze and see which inputs generates special behaviors, and those may be used in future input selection. It then perform mutations to create new inputs, and continue its iteration. Mutation fuzzing starts with a set of inputs, and creates new input by slightly changing these existing data, such as replacing, appending, bit-flipping, etc. It is considered to be less smart and the inputs are less varied, but easier to implement. On the other hand, Generation fuzzing generates new set of inputs everytime based on a model or input format. It covers a wider set of inputs for a larger code paths, despite being harder to implement. References: [Mutation vs. Generation fuzzing](https://https://www.infosecinstitute.com/resources/hacking/fuzzing-mutation-vs-generation/), [Grey-box fuzzing](https://www.fuzzingbook.org/html/GreyboxFuzzer.html) ### (b) To find vulnerablities, I used AFL++ fuzzer. The following are the PoCs found by the fuzzer: #### 1. Vulnerability 1: PoC `id:000001,sig:11,src:000001,time:17235,execs:898,op:flip1,pos:13` - This is a crash record. - Run the file directly `./fuzzTest -i ./fuzz_out/default/crashes/"id:000001,sig:11,src:000001,time:17235,execs:898, op:flip1,pos:13"` and I got the error: **Segmentation fault**. - Furthermore, compile the file with *ASan* using command: `gcc -fsanitize=address -g -o asan ./app.c` - Run the file compiled in the previous step to analyze the error: `ASAN_OPTIONS=verbosity=1 ./asan -i /fuzz_out/default/crashes/"id:000001,sig:11,src:000001,time:17235,execs:898,op:flip1,pos:13"` - ![image](https://hackmd.io/_uploads/H1oFD4iE0.png) - From the part above of the output file, we can find out the function `dHGWZ3BU0MMSmMqXhNDLey7N` caused the Segmentation Fault. Go back to `app.c` and found out the variable passed to it `cv8a78xzjs81ka8xka8fs` is set `NULL` in *Line 791*. This cause the function to fail Segmentation Fault as the address points to the zero page. #### 2. Vulnerability 2: PoC `id:000004,sig:06,src:000001,time:154556,execs:7620,op:havoc,rep:2` - This is a crash record. - Run `./fuzzTest -i ./fuzz_out/default/crashes/"id:000004,sig:06,src:000001,time:154556,execs:7620,op:havoc,rep:2"` - Got the result: `*** stack smashing detected ***: terminated` - Analyze with *AMad*: `ASAN_OPTIONS=verbosity=1 ./asan -i ./fuzz_out/default/crashes/"id:000004,sig:06,src:000001,time:154556,execs:7620,op:havoc,rep:2"` - ![image](https://hackmd.io/_uploads/Hyeei4sN0.png) - From the result above, we know that it is a **Buffer Overflow** error. The error sourced from function `alpKX7wAPFzJbXzjZTOQi4ym` at *Line 366*. Go back to `app.c` and found out in the for loop at *Line 365*, variable `xUJ3fFc1NxYNEjt6X4W0pWvQ` exceeded 1000. The value is then passed to the size-1000 varaible `rm7QkP0YhYIxpk8hjeRtvTRA`, causing the error. #### 3. Vulnerability 3: PoC `id:000000,src:000001,time:6135,execs:335,op:quick,pos:18` - This is a hang record. - Use GDB to find out the reason of hang:`gdb ./fuzzTest` - `run -i ./fuzz_out/default/hangs/id:000000,src:000001,time:6135,execs:335,op:quick,pos:18`, the debugger returns the part where the program hanged: ![image](https://hackmd.io/_uploads/B1Uigfj4R.png) - It appeared to be an **infinity loop**, stuck at the while loop starting from *Line 712*. The variable `LfEL1RFxW94NUwWGjxL00Zos` is always greater than 0, so it will never leave the loop. ## 2. ### (a) Flag: CNS{N33DH4M_5CHR03D3R_PR070C0L_15_4W350M3_8e7c1985126d2142b87cdbc8ccca86aa} - Draw a sequence diagram of the protocol: ![p2-a](https://hackmd.io/_uploads/SkJvHZk40.svg) - Then, register an account on KDC: ``` Enter your username: cnsStudent Enter your password: cnsStudent --------------------------------- Account created successfully! ... ``` - Login and communicate with Bob as the following: - Request session key from server using `3. Request Session Key` with `bob` and with nonce `cns`. Received message $m_{server}$. - Decrypt $m_{server}$ with python program `code2-1-a.py`, with symmetric key $K_s$. Message with format cns$||K_{AB}||$bob$||m_{forward}$ is parsed. - $m_{forward}$ to Bob and get message $m_{nonceB}$ - Decrypt $m_{nonceB}$ with python program `code2-1-b.py` to get $N_{bob}$. Encrypt $N_{bob} - 1$ with $K_{AB}$ and send it back. - Received the final message $m_{flag}$ - Decode $m_{flag}$ with the following code: ``` python message = {encoded message} message = cns_decrypt(key_AB, {encoded message}).decode() print(message) ``` - Received message: `Oh you are CNS student! Here is your flag: CNS{N33DH4M_5CHR03D3R_PR070C0L_15_4W350M3_8e7c1985126d2142b87cdbc8ccca86aa}` ### (b) Flag: Welcome admin! Here is the flag: CNS{D0N_7RY_7H15_47_H0M3_e340c50d4e72213257bab1a0deb4a2bd} Use Python program `code2-b.py` to crack the hash with offline dictionary attack. Apply SHA-256 on each of the strings in file `common_roots.txt`, and find the one that has the same hash as the hash in `admin.password` of `kdc.py`. The password `m45t3rm1nd` is obtained. Login with: ``` Enter your username: admin Enter your password: m45t3rm1nd ``` and get the flag. ### \(c) Flag: CNS{R3PL4Y_4774CK_15_3V3RYWH3R3?!\_d469fa0bd241f15122bc3aa38e8ed7ee} Impersonate Alice and Bob with the following steps: - Login with admin again, and use `4. View Logs`. Find `keyAB` as $K_{AB}$ and `forward_message` as $m_{forward}$ between Alice and Bob. - Send $m_{forward}$ to Bob, and receive $m_{BA}$. - Decrypt $m_{BA}$ with $K_{AB}$, which is an encoded $N_B$, with the same Python file `code2-a-1.py` as *Problem 2-a* and send the new encrypted $N_B -1$ to Bob. - Receive message $m_{flag}$ and decrypt with $K_{AB}$ and get the following message: `Oh you are Alice! Here is your flag: CNS{R3PL4Y_4774CK_15_3V3RYWH3R3?!_d469fa0bd241f15122bc3aa38e8ed7ee}` The replay attack above is possible because nonce or timestamp are not included in both `encrypted_forward_message` and `encrypted(nonce - 1)`. Hence, if $K_{AB}$ is compermised, the attacker can use any `encrypted_forward_message` to retreive message because Bob does not know if the key is fresh. In KDC server, functions `listenA` and `receive_msg_A` does not check timestamps nor sender, thus, any attacker with any key can perform replay attack. To fix it, we can include a timestamp to verify the freshness. Before Alice sends a message to Bob, she made a request: $$A \rightarrow B: A$$ Bob replys with a timestamp encrypted by his server key. $$B \rightarrow A: \{A, N'_B\}_{K_{BS}}$$ Alice then request from the server that she wants to communicate with Bob: $$A \rightarrow S: A, B, N_A, \{A, N'_B\}_{K_{BS}}$$. Server replys with an encrypted message with timestamp for Bob to check if Alice is fresh. $$S \rightarrow A: {A, B, N_A, \{K_{AB}, A, N'_B\}_{K_{BS}}}_{K_{AS}}$$ Now if the attacker compermise $\{K_{AB}, A\}_{K_{BS}}$, since they cannot forge $\{K_{AB}, A, N'_B\}_{K_{BS}}$ because they $K_{BS}$. Thus, the replay attack is prevented. ## 3. ## 4. ### (1) From `ddos_1.pcapng`, the I/O Graphs in Wireshark shows that the throughput surges bewteen 24 to 25 second. Go back to the packet list and find the the packets around the time. We can see that a large amount of UDP packets are sent starting from `time = 24.945277`. Check the stats of the starting packet and get **time: 24.945277, victim IP: 192.168.232.95**. ### (2) Find the `Info` fields of the packets. They record that the packets are sent from Port 123, which is the NTP port. Thus, the attacker exploits the **NTP protocol**. Check the packet lenght of the UDP packets. They are all **482 bytes**. ### (3) The victim sent TCP SYN and ACK packets, which are the packets only clients send. Also, it reached out to other IPs' 443 port. Both implies that the victim is a **client**. Observe the DDoS packets. In the *Info* section, it shows that the packets are sent from port `123 -> 443`. This implies that the attacker wants to perform denial of service on the victim's HTTPS port, disallowing the victim to connect to websites using HTTPS. ### (4) Check the packets in Wireshark, and find the destinations that received a large amount of NTP packets. The victim are as the following: - Victim 1: - IP: 192.168.232.10 - Packet count: 26870 - Three major amplifiers: - 1. 34.93.220.190 - 2. 5.104.141.250 - 3. 124.120.108.157 - Victim 2: - IP: 192.168.232.80 - Packet count: 28320 - Three major amplifiers: - 1. 128.111.19.188 - 2. 129.236.255.89 - 3. 124.120.108.157 - Victim 3: - IP: 192.168.232.95 - Packet count: 23327 - Three major amplifiers: - 1. 34.93.220.190 - 2. 128.111.19.188 - 3. 212.27.110.13 The numbers of packets and major amplifiers were found in *IP4 Statistic > Destination and Ports* and *IP4 Statistic > Sources and Ports* with *IP.dist* filters applied. ### (5) Use `sudo tcpdump -i eth0 src host 142.44.162.188 -w ddos.pcapng` to capture the traffic of the amplifier and output the file. Send a monlist query with `nmap -sU -p 123 --script=ntp-monlist 142.44.162.188`, while listening to the traffic. End the listener after monlist was send. Open `ddos.pcapng` with wireshark and count: $Output \; Packet \;Count /\; Input\; Packet\; Count = 103/3$. The amplification factor is around $34.33$. ### (6) As the operator of the amplifier, I can set up rate limit for packets received from a single IP, preventing the server being used by the victim. Also, I should turn of unused ports like NTP or DNS, which are often used in amplification attacks. As the network administrator, I can also set up rate limit for the incoming packets, or use firewall to block IPs that sends an unusual amount of packets. Also, purchase devices that can mitigate the traffic or redirect into other unused IP (blackhole), preventing my device to be flooded with DDoS traffic. ## 5. ## 6. ### (1) Flag: CNS{f1N@L_con7RIbU7iON_47T@cK} The online casino (case 1) noted that the winner will be $\sum^{798}_{i=0} x_i + x_{user} \; mod \; 800$, where $x_i$ is the number for each player. From `casino/case1.py`, we know that the index of user is `799`, and $\sum^{798}_{i=0} x_i$ are known can be calculated. Thus, we only need to manipulate $x_{user}$ and let it be $799 - \sum^{798}_{i=0} x_i \; mod \; 800$. We then repeated enter the calculated $x_{user}$ to win the casino, until we can buy the flag. *The pyhton file for this question is `code6-1.py`* ### (2) Flag: CNS{MT19937PredictorAlsoKnowsThePast!?} In this question, we have to exploit MT19937 PRNG and predict the unknown numbers. I installed this python package `pip install extend_mt19937_predictor` to help predicting the unknown psuedo random numbers. According to [Reference](https://en.wikipedia.org/wiki/Mersenne_Twister), we need 624 numbers in order for the predictor to find out the future iterations, thus, there are two cases in this problem: - Case 1: `user_index < 629` Because user 1-5 are VIPs, if `user_id < 629`, there are less than $624$ numbers when we are asked to enter the number. Hence, it's not possible to guess the future iterations and the program enters $0$. - Case 2: `user_index >= 629` Becaues we have more than $624$ numbers, we can then predict both: - The numbers of users who's index is greater than `user_index` - The VIPs with index `0-4`. After knowing these numbers, we can obtain the guess by letting it be $k - \sum^{799}_{i=0}x_i \; mod \; 800 \;\;for \; i\ne k$, similar to *problem 6-1*. In this problem, I ran about 150 iterations and got enough money for the flag. *The pyhton file for this question is `code6-2.py`* ### (3)