#!/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 03") 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')