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