Skip to content

Instantly share code, notes, and snippets.

@scottrcarlson
Created August 16, 2018 21:33
Show Gist options
  • Save scottrcarlson/2bc7c954a7a759ffc18b5747e8a3326d to your computer and use it in GitHub Desktop.
Save scottrcarlson/2bc7c954a7a759ffc18b5747e8a3326d to your computer and use it in GitHub Desktop.
DEF CON 26 Badge Emulator (Full Badge Bus Communication Protocol)
#!/usr/bin/python
import time
import serial
from crccheck.crc import Crc16AugCcitt
#DEF CON 26 Badge Bus Communication Emulator
#Requires Python / Python crccheck / TTL USB-to-Serial adapter
#Relevant Sources
#https://github.com/Wireb/badge_bus/wiki
#https://github.com/m0n73/dc26_BadgeEmulator
PREAMBLE = "\x55\x55"
PACKET_START = "\x42\x42"
STATUS_REQ = "\x80"
STATUS_RES = "\xC0"
COMMAND = "\xAF"
PAYLOAD_REQ_LEN = "\x00"
PAYLOAD_RES_LEN = "\x05"
PAYLOAD_BEGIN = "\x00\x01\x00"
TYPE_HUMAN = "\x01"
TYPE_CONTEST = "\x02"
TYPE_GOON = "\x03"
TYPE_ARTIST = "\x04"
TYPE_PRESS = "\x05"
TYPE_VENDOR = "\x06"
TYPE_SPEAKER = "\x07"
TYPE_CFP = "\x08"
STATUS_RED = "\x00"
STATUS_GREEN = "\x01"
def buildPacket(isRequest, badgeType, badgeStatus):
if isRequest:
packet = PACKET_START + STATUS_REQ + COMMAND + PAYLOAD_REQ_LEN
crc = str(hex(Crc16AugCcitt.calc(bytearray(packet))))[2:].decode("hex")
return PREAMBLE + packet + crc
else:
packet = PACKET_START + STATUS_RES + COMMAND + PAYLOAD_RES_LEN + PAYLOAD_BEGIN + badgeType + badgeStatus
crc = str(hex(Crc16AugCcitt.calc(bytearray(packet))))[2:].decode("hex")
return PREAMBLE + packet + crc
def nextBadgePacket(index, status):
if index == 1:
return "Human", buildPacket(False, TYPE_HUMAN, status)
elif index == 2:
return "Contest", buildPacket(False, TYPE_CONTEST, status)
elif index == 3:
return "Goon", buildPacket(False, TYPE_GOON, status)
elif index == 4:
return "Artist", buildPacket(False, TYPE_ARTIST, status)
elif index == 5:
return "Press", buildPacket(False, TYPE_PRESS, status)
elif index == 6:
return "Vendor", buildPacket(False, TYPE_VENDOR, status)
elif index == 7:
return "Speaker", buildPacket(False, TYPE_SPEAKER, status)
elif index == 8:
return "CFP", buildPacket(False, TYPE_CFP, status)
request_packet = buildPacket(True, TYPE_HUMAN, None)
with serial.Serial('/dev/ttyUSB0', 9600, timeout=2) as ser:
time.sleep(0.1)
badgeIndex = 1
while True:
ser.write(request_packet)
time.sleep(0.1)
packet = ''
prev_byte = ''
isRequest = False
isValid = False
parse_state = -1
print "--"
print "Bytes in Buf: " + str(ser.in_waiting)
while ser.in_waiting:
byte = ser.read(1)
if parse_state == -1 and byte == '\x42':
parse_state = 0
elif parse_state == 0 and byte != '\x42' and prev_byte == '\x42': #Packet Start
parse_state = 1
if byte == STATUS_REQ:
print "Receiving Request Packet"
isRequest = True
parse_state = 1
elif byte == STATUS_RES:
print "Receiving Response Packet"
parse_state = 1
elif parse_state == 1: #Command Byte 0xAF
if byte == COMMAND:
parse_state = 2
elif parse_state == 2: #Payload Length (0 or 5)
if byte == PAYLOAD_REQ_LEN:
parse_state = 8
print "Payload Length: " + byte.encode("hex")
elif byte == PAYLOAD_RES_LEN:
parse_state = 3
print "Payload Length: " + byte.encode("hex")
elif parse_state == 3 and byte == "\x00": #Payload Byte1
parse_state = 4
elif parse_state == 4 and byte == "\x01": #Payload Byte2
parse_state = 5
elif parse_state == 5 and byte == "\x00": #Payload Byte3
parse_state = 6
elif parse_state == 6:
parse_state = 7
print "Badge Type: " + byte.encode("hex")
elif parse_state == 7:
print "Badge Status: " + byte.encode("hex")
parse_state = 8
elif parse_state == 8:
parse_state = 9
elif parse_state == 9:
parse_state = 10
prev_byte = byte
if parse_state >= 0 and parse_state <= 10:
packet += byte
if parse_state == 10:
parse_state = 11
crc = hex(Crc16AugCcitt.calc(bytearray(packet[:-2])))[2:]
crc_recv = packet[-2:].encode("hex")
print "Packet: " + str(packet[:-2]).encode("hex")
print "Calc/Recv CRC: %s/%s " % (crc, crc_recv)
if crc == crc_recv:
isValid = True
print "!! VALID PACKET !!"
if isRequest and isValid:
type, packet = nextBadgePacket(badgeIndex, STATUS_GREEN)
ser.write(packet)
print "== " + type + " Badge Response Sent =="
badgeIndex += 1
if badgeIndex > 8:
badgeIndex = 1
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment