diff --git a/ChatClient/README.md b/ChatClient/README.md index 04c707b..8997c20 100644 --- a/ChatClient/README.md +++ b/ChatClient/README.md @@ -14,10 +14,10 @@ to intercept and read the Messages. In the **Buggs** directory you can find starting code for our simple Whatsapp clone. - - The **main.py** file, is the Entry Point. I dont really expect you to modify this. + - The **main.py** file, is the Entry Point. I don't really expect you to modify this. HOWEVER, you can change the logging level to remove debugging messages - The **network** file contains the base networking code. You can Ignore this. - - The twho **Driver.py** file is what you need to edit. + - The two **Driver.py** file is what you need to edit. ### Driver Code @@ -72,7 +72,7 @@ As we are sending the Data Locally, lets set the interface to be Loopback (as it If you have already used wireshark, you can set the current interface using **capture** -> **options** Once you select the interface Wireshark will start capturing Packets. (You may have to click the Fin Icon in the top Left) -Start the Chat program again, and send a few messages. Once you are done exit the chat **-1** and click the red *stop-captyre* icon in wireshark +Start the Chat program again, and send a few messages. Once you are done exit the chat **-1** and click the red *stop-capture* icon in wireshark ![Packet Information](images/Wireshark-Captured.png) @@ -89,7 +89,7 @@ In the image below I have highlighted one packet where we are sending data. ![Wireshark Inspect](images/Wireshark_PacketDetails.png) You can see at the bottom of the screen we have the raw packet information. -And the data iteslf. +And the data itself. Obviously an attacker could also use this (if they had access to the network) to view the chat messages we send. @@ -110,7 +110,7 @@ We can also use the chat client to talk to another Machine !!! important You need to put your Kali Box in Bridged mode for this - Othwerise we cannot access the main network + Otherwise we cannot access the main network For this we need a Pair of IP addresses. Yours and the Target On each machine you need to: @@ -134,7 +134,7 @@ Capture the traffic again and see if you can identify the messages. ## Part 2: Changing the Behaviour of the Client Before we get adding encryption lets look at changing the behaviour of the chat -The two *driver* files contain the logic for sending and recieving data. +The two *driver* files contain the logic for sending and receiving data. ### Changing the Send Logic. @@ -155,10 +155,10 @@ Lets change the Code to Prefix Everything with "MESSAGE" !!! note "Keeping the Code Sane" We could do this in-place, but to keep the code sane we are going to create a - a new funciton to modify the data. + a new function to modify the data. - This means we can just change the function, rahter than have to fix the - send message code each time we make a modifiaction + This means we can just change the function, Rather than have to fix the + send message code each time we make a modification ```python @@ -205,7 +205,7 @@ For example. We could print an all uppercase version of the Input using the cod Lets continue the password task. Change the receive code to take the hash that you have sent - in the task above. And check it against a known hash (ie the correct password) + in the task above. And check it against a known hash (IE the correct password) Print a message if the login is successful @@ -216,7 +216,7 @@ For example. We could print an all uppercase version of the Input using the cod The output may be a bit confusing when you are running locally, as you are sending a message back to yourself (thus everything is in one window) - Rememebr you can also send to anopther machine + Remember you can also send to another machine @@ -286,11 +286,143 @@ RESONSE FROM SERVER b'BAR' !!! task "Login Client" - Modify the hash sending and checking code you developed eariler + Modify the hash sending and checking code you developed earlier to simulate a login process. Get the server to send a message back to the client if login was - successfull + successfully + + +!!! task "Use Wireshark to capture the communication" + + Use Wireshark to capture the communication again + Identify where the Hash is being sent + +!!! task "Can you login without knowing the password?" + + Imagine you have intercepted the message. But don't know + the password. + + Could you complete the login process using the information + from wireshark? + + (You can even do this without python, try using netcat) + + +## Basic AES Encryption + +You can see that the message is still transmitted in plain text. +So we will add AES encryption to our program. + +The **aesDemo.py** program has a simple example of encrypting and decryption data + + +Link to [Pycryptodome AES documentation](https://pycryptodome.readthedocs.io/en/latest/src/cipher/aes.html) + +!!! note "Requirements" + + You need to install pycrypotome + + ```pip install pycryptodome``` + + +!!! task + + Take a look through the AES Demo Code and see how it works + + Modify the code to allow the user to specify a message + + + +!!! task + + Modify the Client Server Code to Encrypt and Decrypt messages + using a Static Key and IV + +!!! task + + Use Wireshark to intercept the messages. + Identity where the code is being sent. + + Try to decrypt the intercepted message... + +## AES with user specified passwords + +Or last example has the problem that both the Key and IV are static +This time we will modify the code to allow the users to specify a key + + +WE can use the [PBKDF](https://pycryptodome.readthedocs.io/en/latest/src/protocol/kdf.html?highlight=PBKDF#Crypto.Protocol.KDF.PBKDF2) +functions to help us generate a key. + +For example: + +```python + +from Crypto.Protocol.KDF import PBKDF2 + +salt = "SALT" +password = "userInput" + +key = PBKDF2(password, salt) +print(key) +``` + +!!! task + + Modify the code to allow the user to specify a password. + + 1. Check that you can send and receive when both sides have the same password + 1. What happens if the password differs on each side. + +## Sending the Key Across the Network + +Now lets look at sending the key across the network. (To simulate a HTTP style connect) + +The Logic for our program looks something like this + + 1. Client Connects to the Server + 2. Server Generates a new random key and sends it to the client + 3. Key is used in all future comms + + +WE will need create a basic protocol for this. +I would suggest adding a prefix to control messages (which we can then look for and process) + +for example ```KEY:``` when sending a key. + +!!! task "Server Generated Keys" + + Modify the code so that the server generates the key (using the algorithm above) + To keep things simple (at them moment use a static IV) + + 1. Check that The Communication works as Expected + 2. Use Wireshark to intercept the Key exchange and message + 3. Can you decrypt messages that are sent? + + Bonus Task + + 1. Generate a random IV and send it across + 1. Can you intercept the parts of the message in wireshark and Decrypt? + + +## (Optional) Key Exchange + +You can see that if we can capture the key exchange we can still decrypt message. +Lets try to implement a DH style key exchange + + + + +!!! task "Diffie Hellman" + + Implement a basic version of Diffie Helman Key-exchange + Does this stop our attacker being able to capture the packets + + [This Code is a good starting point](https://sublimerobots.com/2015/01/simple-diffie-hellman-example-python/) + + + diff --git a/ChatClient/buggs/aesDemo.py b/ChatClient/buggs/aesDemo.py new file mode 100644 index 0000000..5bbd957 --- /dev/null +++ b/ChatClient/buggs/aesDemo.py @@ -0,0 +1,54 @@ +from Crypto.Cipher import AES + +#Our Static Key +KEY = b"ThisIsAStaticKey" +IV = b"ThisIsAnStaticIV" + +def encryptMessage(message, IV=None): + """Encrypt a message using a static key""" + + #Create a AES object We use CFB as we dont need to Pad the object input + cipher = AES.new(KEY, AES.MODE_CFB, iv=IV) + + #Encode the Data + enciphered = cipher.encrypt(message) + + #The IV is automagically Generated for us + IV = cipher.iv + + #REturn them + return enciphered, IV + + + +def decryptMessage(message, IV): + """ + Given a message and a IV + Decrypt the data using a static key + """ + + cipher = AES.new(KEY, AES.MODE_CFB, iv=iv) + + #Deode the Data + deciphered = cipher.decrypt(message) + + return deciphered + + + +if __name__ == "__main__": + + + + message = b"Hello World" + + #Use a Static IV + code, iv = encryptMessage(message, IV) + print("Cipher Text is {0}".format(code)) + print("IV is {0}".format(iv)) + + #Then Decipher + + decode = decryptMessage(code, iv) + print("Decoded Message {0}".format(decode)) +