Guest User

Untitled

a guest
Jan 21st, 2018
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.01 KB | None | 0 0
  1. #!/usr/bin/python
  2. ## Trusted Neighbour Discovery Protocol POC
  3. ##
  4. ##
  5. ## The Trusted Neighbour Discovery Protocol is a protocol which can be used to identify computers
  6. ## on a local LAN that share a common secret and set up trusted communication channels bewteen them
  7. ## at the same time.
  8. ## The TNDP uses standard challenge response mechanisms to provide mutual authentication between
  9. ## two holders of a common secret.
  10. ## After mutual authentication, TNDP uses Diffie Hellman to create a shared session key for
  11. ## secure communication. However, by choosing the random challenge nonces from a publicly known
  12. ## algebraic group, TNDP integrates the Diffie Hellman key exchange mechanism in the challenge
  13. ## response phase, improving efficiency by two rounds.
  14. ## The POC implemenation scans the local lan for computers running the POC while listening for
  15. ## connections from other computers.
  16. ## Once a neighbour has been identified and authenticated, the listener uses the newly created
  17. ## secure channel to send some user-specified flag data
  18. ##
  19. ##                                 TNDP overview:
  20. ##    Neighbour1                                          Neighbour2
  21. ##    
  22. ##    (shared secret k)                                   (shared secret k)                    
  23. ##                                    HELLO
  24. ##                                -------------->
  25. ##                                                        pick random secret x
  26. ##                                                        nonce_1 = g^x  (Diffie Hellman public key)
  27. ##                                    nonce_1          
  28. ##                                <--------------
  29. ##    pick random secret y
  30. ##    nonce_2 = g^y
  31. ##    encrypt nonces using k
  32. ##                              {nonce_1, nonce_2}k
  33. ##                                -------------->
  34. ##                                                        check validity of nonce_1
  35. ##                                                        calculate shared secret s = nonce_2^x
  36. ##                                    nonce_2          
  37. ##                                <--------------
  38. ##    check validity nonce_2
  39. ##    calculate shared secret
  40. ##    s = nonce_1                
  41. ##                                 {secure data}s          
  42. ##                                <------------->
  43. ##
  44.                                
  45. from Crypto.Cipher import AES
  46. from Crypto.Util import number
  47. from Crypto.Util import randpool
  48.  
  49. import hashlib
  50. import struct
  51. import socket
  52. import os
  53. import sys
  54. import time
  55.  
  56. ips = [ "192.168.120.186", "192.168.120.1", "192.168.120.115", "192.168.120.119", "192.168.120.121", "192.168.120.122", "192.168.120.125", "192.168.120.127", "192.168.120.133", "192.168.120.145", "192.168.120.146", "192.168.120.148", "192.168.120.149", "192.168.120.157", "192.168.120.160", "192.168.120.182", "192.168.120.185", "192.168.120.198" ]
  57.  
  58. # helper function because python doesn't support conversion of numbers larger than 64 bits    
  59. def toBytes(largeNum):
  60.     part2 = largeNum & 0xFFFFFFFFFFFFFFFF
  61.     part1 = largeNum >> 64
  62.     byteForm = struct.pack('Q', part1) + struct.pack('Q', part2)
  63.     return byteForm
  64.  
  65. # helper function because python doesn't support conversion to numbers larger than 64 bits    
  66. def toNum(byteForm):    
  67.     part1 = struct.unpack("Q", byteForm[0:8])
  68.     part2 = struct.unpack("Q", byteForm[8:16])
  69.     largeNum = (part1[0] << 64) + part2[0]
  70.     return largeNum
  71.  
  72. # the listener, spawns a separate process for each incoming connection
  73. def startListener(port):
  74.     sock = socket.socket();
  75.     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  76.     sock.bind(("0.0.0.0", port));
  77.     sock.listen(5);
  78.     while(True):
  79.         (c, a) = sock.accept()
  80.         pid = os.fork()
  81.         if (pid):
  82.             handleIncoming(c, a)
  83.             break
  84.        
  85. # the incoming connection handler,
  86. def handleIncoming(connection, address):
  87.     inp = connection.recv(6)
  88.     if (not inp[0:5] == "HELLO"):
  89.         connection.shutdown(socket.SHUT_RDWR)
  90.         connection.close()
  91.         print "connection closed after hello"
  92.         sys.exit()
  93.  
  94.     generator = randpool.RandomPool()
  95.     secret = number.getRandomNumber(128, generator.get_bytes)
  96.     pub = pow(g, secret, prime)
  97.     connection.send(toBytes(pub))  # sending nonce1
  98.    
  99.     inp = connection.recv(32)  # receiving encrypted nonces
  100.     print inp.encode('hex')
  101.     if (not len(inp) == 32):
  102.         print "incoming closed: invalid response size"
  103.         connection.shutdown(socket.SHUT_RDWR)
  104.         connection.close()
  105.         sys.exit()
  106.     decrypted = cipher.decrypt(inp)
  107.     pubTest = toNum(decrypted[0:16])
  108.     if (not pubTest == pub):
  109.         connection.shutdown(socket.SHUT_RDWR)
  110.         connection.close()
  111.         print "incoming closed: authentication failed"
  112.         sys.exit()
  113.     pub2 = toNum(decrypted[16:32])
  114.     connection.send(decrypted[16:32]) # sending nonce2
  115.    
  116.     sharedSecret = pow(pub2, secret, prime)
  117.     sharedCipher = makeCipher(toBytes(sharedSecret))
  118.  
  119.     print "incoming successful: sending flag"
  120.     connection.send(sharedCipher.encrypt(paddedString(flag)))
  121.    
  122.     connection.shutdown(socket.SHUT_RDWR)
  123.     connection.close()
  124.     sys.exit()
  125.    
  126.    
  127. def startFinder(port):
  128.     connections = []
  129.     ipaddr = "192.168.120.145"
  130.     while(True):  
  131.         for i in ips:
  132.             if (not i == ipaddr):
  133.                 sock = socket.socket()
  134.         sock.settimeout(1)
  135.         print i
  136.         try:
  137.             sock.connect((i, port))
  138.             pid = os.fork()
  139.             if (pid):
  140.                 handleOutgoing(sock)
  141.         except Exception as e:
  142.             sock.close()
  143.                 time.sleep(1)
  144.  
  145. def handleOutgoing(sock):
  146.     print "starting outgoing"
  147.     sock.send("HELLO")
  148.     inp = sock.recv(16) # receiving nonce1
  149.     if (not len(inp) == 16):
  150.         print "outgoing closed: invalid riesponse size nonce1"
  151.         sock.shutdown(socket.SHUT_RDWR)
  152.         socket.close()
  153.         sys.exit()
  154.        
  155.    
  156.     pub2 = toNum(inp)
  157.     generator = randpool.RandomPool()
  158.     secret = number.getRandomNumber(128, generator.get_bytes)
  159.     pub = pow(g, secret, prime)
  160.     encrypted = cipher.encrypt(inp + toBytes(pub))
  161.     sock.send(encrypted) #sending encrypted nonces
  162.    
  163.     inp = sock.recv(16) # receiving nonce2
  164.     print "nonce2 = "  + inp + ", len=" +  str(len(inp))
  165.     if (not len(inp) == 16):
  166.         print "outgoing closed: invalid response size nonce2, len = " + str(len(inp))
  167.         sock.shutdown(socket.SHUT_RDWR)
  168.         sock.close()
  169.         sys.exit()
  170.    
  171.     pubTest = toNum(inp)
  172.     if (not pubTest == pub):
  173.         sock.shutdown(socket.SHUT_RDWR)
  174.         sock.close()
  175.         print "outgoing closed: authentication failed"
  176.         sys.exit()
  177.  
  178.    
  179.     sharedSecret = pow(pub2, secret, prime)
  180.     sharedCipher = makeCipher(toBytes(sharedSecret))
  181.  
  182.     inp = sock.recv(32)
  183.     print("outgoing succesfull: flag = " + sharedCipher.decrypt(inp))
  184.     sock.shutdown(socket.SHUT_RDWR)
  185.     sock.close()
  186.     sys.exit()
  187.  
  188.  
  189. def makeCipher(password):
  190.     key = hashlib.sha256(password).digest()
  191.     cipher = AES.new(key, AES.MODE_ECB)
  192.     return cipher
  193.  
  194. def paddedString(string):
  195.     return string + (" " * (16 - (len(string) % 16) % 16))
  196.  
  197.  
  198. password = "password"
  199. if (len(sys.argv) > 1):
  200.     password = sys.argv[1]
  201. flag = "flag"
  202. if (len(sys.argv) > 2):
  203.     flag = sys.argv[2]
  204.    
  205. cipher = makeCipher(password)
  206. prime = 234240772648780971299441373185329797673L
  207. g = 304615143433536066436723092374584571969L
  208.    
  209.  
  210.  
  211. print "starting finder"
  212. startFinder(22223)
Add Comment
Please, Sign In to add comment