Sweetening

Actual P2P Chat Client

Jul 29th, 2023
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.01 KB | None | 0 0
  1. #!/usr/bin/python
  2. # NSA P2P Chat Client
  3. # -*- coding: utf-8 -*-
  4. import sys
  5. import socket
  6. import base64
  7. import random
  8. import string
  9. import hashlib
  10. from Crypto.Cipher import AES
  11. from Crypto import Random
  12. from threading import Thread
  13. import getpass
  14.  
  15.  
  16. class CryptoClient(object):
  17. def __init__(self):
  18. print("Welcome to CryptoChat, a secure P2P chat client coded by Freak")
  19. print("if you don't know what you're doing, read the README.md!!!")
  20. self.IP = input("Please enter the IP address you wish to chat with: ")
  21. self.PORT = int(input("Enter the port for communication: "))
  22. print()
  23. print("Now enter the keys for the different encryption methods, make sure they are different.")
  24. print("Please note they will not be printed for your security.")
  25. print()
  26. self.EncryptKeyXOR = getpass.getpass("Enter desired key for XOR encryption: ")
  27. self.EncryptKeyAES = hashlib.md5(getpass.getpass("Enter a secure passphrase for AES: ").encode()).hexdigest()
  28. print()
  29. input("Press enter when both clients are ready.")
  30. ###Shit for AES padding
  31. BS = 16
  32. self.pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
  33. self.unpad = lambda s: s[:-ord(s[len(s) - 1:])]
  34. ###Start chat server and client
  35. try:
  36. Thread(target=self.RecvMSG, args=()).start()
  37. except socket.error as e:
  38. print(self.IP + " is not ready! Press enter when " + self.IP + " is ready.")
  39. input()
  40. Thread(target=self.RecvMSG, args=()).start()
  41. self.SendMSG()
  42.  
  43. def EncryptAES(self, raw):
  44. raw = self.pad(raw)
  45. iv = Random.new().read(AES.block_size)
  46. cipher = AES.new(self.EncryptKeyAES.encode(), AES.MODE_CBC, iv)
  47. return base64.b64encode(iv + cipher.encrypt(raw.encode())).decode()
  48.  
  49. def DecryptAES(self, enc):
  50. enc = base64.b64decode(enc)
  51. iv = enc[:16]
  52. cipher = AES.new(self.EncryptKeyAES.encode(), AES.MODE_CBC, iv)
  53. return self.unpad(cipher.decrypt(enc[16:])).decode()
  54.  
  55. def XOR(self, securekey, data, mode):
  56. if mode == 1:
  57. securekey = securekey[::-1]
  58. temp = ''
  59. for char in securekey:
  60. for x in data:
  61. temp += chr(ord(x) ^ ord(char))
  62. data = temp
  63. temp = ''
  64. return data
  65.  
  66. def EncryptMSG(self, data):
  67. data = self.XOR(self.EncryptKeyXOR, data, 0)
  68. data = self.EncryptAES(data)
  69. return data
  70.  
  71. def DecryptMSG(self, data):
  72. data = self.DecryptAES(data)
  73. data = self.XOR(self.EncryptKeyXOR, data, 1)
  74. return data
  75.  
  76. def SendMSG(self):
  77. clientsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
  78. print()
  79. print("You are now talking to '" + self.IP + "'")
  80. while True:
  81. message = input("")
  82. if message.startswith("/send"): # send file command
  83. self.SendFILE(message.split(" ")[1])
  84. continue
  85. if message == "/leave":
  86. message = self.EncryptMSG("\x03")
  87. clientsock.sendto(message.encode(), (self.IP, self.PORT))
  88. sys.exit(0)
  89. if message.startswith("/msg"):
  90. self.IP = message.split(" ")[1]
  91. print("[CLIENT] You are now talking to '" + self.IP + "'")
  92. continue
  93. else:
  94. message = self.EncryptMSG("\x01" + message)
  95. clientsock.sendto(message.encode(), (self.IP, self.PORT))
  96.  
  97. def SendFILE(self, file_):
  98. if file_.startswith(".") or file_.startswith("/"): # added security measure.
  99. print("[CLIENT] For security and safety reasons, filenames starting with '.' or '/' will not be sent. Aborting.")
  100. else:
  101. clientsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
  102. data = "\x02" + file_ + "\xFF"
  103. with open(file_, "rb") as f:
  104. data += f.read()
  105. data = self.EncryptMSG(data)
  106. clientsock.sendto(data.encode(), (self.IP, self.PORT))
  107. print("[CLIENT] File Sent!")
  108.  
  109. def RandStr(self, length):
  110. return ''.join(random.choice(string.ascii_letters) for _ in range(length))
  111.  
  112. def RecvMSG(self):
  113. serversocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP
  114. serversocket.bind(('', self.PORT))
  115. while True:
  116. data, addr = serversocket.recvfrom(1073741824) # buffer size is 1 gbit (for large files/images)
  117. data = self.DecryptMSG(data.decode())
  118. if data.startswith("\x02"):
  119. filename = ''
  120. data = list(data)
  121. del data[0]
  122. for i in data:
  123. if i == "\xFF":
  124. break
  125. else:
  126. filename += i
  127. del data[0] # delete protocol char
  128. del data[:len(filename)] # delete file end char
  129. if filename.startswith(".") or filename.startswith("/"): # attempted exploit!
  130. print("[!!!ALERT!!!] " + addr[0] + " has attempted to overwrite your " + filename)
  131. else:
  132. print("[CLIENT] " + addr[0] + " has sent " + filename)
  133. print("[CLIENT] Downloading...") # download dat shit
  134. data = ''.join(data)
  135. with open(filename, "wb") as f:
  136. f.write(data.encode())
  137. print("[CLIENT] Saved.")
  138. elif data.startswith("\x01"): # all messages start with "\x01" to prevent file spamming
  139. data = list(data)
  140. del data[0]
  141. data = ''.join(data)
  142. print("[" + addr[0] + "] > | " + data)
  143. elif data.startswith("\x03"):
  144. print("[CLIENT] " + addr[0] + " has left.")
  145. sys.exit(0)
  146.  
  147.  
  148. if __name__ == "__main__":
  149. CryptoClient()
  150.  
Add Comment
Please, Sign In to add comment