Newer
Older
BLE_CTF_V2 / lvl_03.py
root on 11 Mar 2022 4 KB tidying for public release
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from __future__ import print_function # import print from python3: end=""
  4. import time
  5. import re
  6. import pexpect # sudo apt-get install python-pexpect
  7. import subprocess
  8. import random
  9. import binascii
  10. import struct
  11. import sys, os, time
  12. import bluepy.btle as btle
  13.  
  14. '''
  15. Service <uuid=Heart Rate handleStart=40 handleEnd=65535>
  16. 42 0x2A READ Connect with pin 0000. Try using bluetoothctl
  17.  
  18. b46fa238cf820d0f60c1
  19. '''
  20.  
  21. # !!! make sure bluetoothd runs in --compat mode before executing this script !!!
  22. 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)
  23. "exectutes pairing with entered PIN on bluetooth adapter side"
  24. try:
  25. newpid = os.fork()
  26. if newpid == 0:
  27. time.sleep(5)
  28. '''
  29. Start bluepy stuff
  30. '''
  31. subprocess.call(['hciconfig','hci0','down'])
  32. subprocess.call(['hciconfig','hci0','up'])
  33.  
  34. deviceMAC = open('ctf_mac.txt').read()
  35. p = btle.Peripheral(deviceMAC)
  36. svc=p.getServiceByUUID("0000180d-0000-1000-8000-00805f9b34fb")
  37. print ("Attached to peripheral (pid 0)")
  38. hex1 = p.readCharacteristic(0x2C)
  39. hex2 = binascii.b2a_hex(hex1)
  40. hexlif2 = str(binascii.unhexlify(hex2))
  41. print("Flag: "+hexlif2)
  42. p.disconnect()
  43. exit()
  44. else:
  45. '''
  46. Start actual pair stuff
  47. '''
  48. subprocess.call(['hciconfig','hci0','sspmode', '0'])
  49. # bluetoothctl
  50. print("Pairing")
  51. child = pexpect.spawn('bluetoothctl')
  52. child.logfile = open("/tmp/mylog", "w")
  53. child.expect("#")
  54. child.sendline('agent off') # might be unnecessary
  55. #child.sendline('scan on') # might be unnecessary
  56. child.expect("unregistered")
  57. child.sendline('agent KeyboardDisplay ')
  58. child.expect("Agent registered")
  59. child.sendline('pairable on')
  60. child.expect("pairable on succeeded")
  61. child.sendline('discoverable on')
  62. child.expect("discoverable on succeeded")
  63. child.sendline('default-agent')
  64. child.sendline('remove 3c:71:bf:f1:ef:c6')
  65. child.sendline('scan on')
  66. child.expect("Device 3C:71:BF:F1:EF:C6 FLAG_3")
  67. child.sendline('pair 3c:71:bf:f1:ef:c6')
  68.  
  69. child.expect('Request passkey', timeout = time_limit ) # timeout <= PAIRING_TIME_LIMIT to keep some kind of logic
  70. print ('Sending PIN: ' + pin)
  71. child.sendline(pin)
  72. i = child.expect(['Paired: yes', 'Enter passkey:'], timeout = time_limit)
  73. if i == 0: # found 'Paired: yes' == successful pairing
  74. trust_mac = 'trust ' + re.search(r'(?:[0-9a-fA-F]:?){12}.+$', child.before).group(0) # extract MAC from last line, one with 'Paired: Yes'
  75. child.sendline(trust_mac) # optionally add device to trusted
  76. child.expect('trust succeeded', timeout = 10)
  77. pairing_status = True
  78. child.sendline('remove 3c:71:bf:f1:ef:c6')
  79. else: # i == 1
  80. print('wrong PIN, retrying if time will allow')
  81. except pexpect.EOF:
  82. print ('!!!!!!!! EOF')
  83. except pexpect.TIMEOUT:
  84. print ('!!!!!!!! TIMEOUT')
  85. # hide Pi's bluetooth for security reasons
  86. child.sendline('pairable off')
  87. child.expect("pairable off succeeded")
  88. child.sendline('discoverable off')
  89. child.expect("discoverable off succeeded")
  90. child.close()
  91. return pairing_status
  92.  
  93. #main program body
  94. PAIRING_TIME_LIMIT = 60
  95. BT_PIN = "0000" # random.randint(1000,10000) # generate random 4-digit PIN 1000..9999
  96.  
  97. deviceMAC = open('ctf_mac.txt').read()
  98. p = btle.Peripheral(deviceMAC)
  99. svc=p.getServiceByUUID(0x00FF)
  100. print ("Attached to peripheral")
  101.  
  102. print("Loading level 03")
  103. hex1 = binascii.unhexlify(str('%0*x' % (4,3)))
  104. p.writeCharacteristic(0x30, hex1, withResponse=False)
  105.  
  106. p.disconnect()
  107.  
  108. status = pair_with_pin(int(time.time()), str(BT_PIN), PAIRING_TIME_LIMIT)
  109. if status == True:
  110. print('Pairing successful')
Buy Me A Coffee