-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinteractive_brute_force.py
180 lines (150 loc) · 6.05 KB
/
interactive_brute_force.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
'''
CanBus - Interactive Brute Force
Eric Turner
6 May 2023
This script allows you use your arrow keys / enter to interface with the cluster.
Also allows you to test brute force options
'''
import can
import time
from pynput import keyboard
from multiprocessing.pool import ThreadPool as Pool
from random import randint
key = None
start = time.time()
# VARIABLES
# change the channel and bitrate as needed
bus = can.interface.Bus(bustype='slcan', channel='COM3', bitrate=500000)
speed = 0.1 # speed in ms to send messages
can_ids = (0x37,) # tuple of CAN Ids to brute force. They will all be set to the same
seq_bytes = (4,) # if using sequential, the bytes to increment through
sample_data = [0x37, 0x00, 0x00, 0x00, 0xC0, 0x7A, 0x37, 0x1C] # sample set of data to start with
# SAMPLE DATA - 2015 Ford Mustang GT - Manual - MyColor
# 200 => [0x00, 0x00, 0x7F, 0xF0, 0x81, 0x57, 0x00, 0x00]
# 204 => [0xC0, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00]
# 3B3 => [0x40, 0x8B, 0x0a, 0x12, 0x18, 0x05, 0xC0, 0xE2]
def send_msg(id, ts, data, verbose=True):
try:
msg = can.Message(timestamp = time.time() - ts, arbitration_id=id,
data=data,
is_extended_id=False)
bus.send(msg)
if (verbose):
print(msg, end="")
except can.CanError:
print(" {} - Message NOT sent".format(str(hex(id))))
def arrows_test(direction):
UP = 0x08
DOWN = 0x01
LEFT = 0x02
RIGHT = 0x04
ENTER = 0x10
data = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
if(direction == 'up'):
data[0] = UP
elif(direction == 'down'):
data[0] = DOWN
elif(direction == 'left'):
data[0] = LEFT
elif(direction == 'right'):
data[0] = RIGHT
elif(direction == 'enter'):
data[0] = ENTER
send_msg(0x81, start, data, verbose=False)
print('')
def on_press(key):
try:
k = key.char # single-char keys
except:
k = key.name # other keys
if k in ['up', 'down', 'left', 'right', 'enter']: # keys of interest
# self.keys.append(k) # store it in global-like variable
print('Key pressed: ' + k)
arrows_test(k)
#return k # stop listener; remove this if want more keys
'''
Generates a random byte from 0x00 to 0xFF in order
Pass a tuple index to modify the sample data to the random byte for a brute force method of determining what the code does
'''
def send_on():
while(True):
send_msg(0x3B3, start, [0x40, 0x8B, 0x02, 0x0a, 0x18, 0x05, 0xC0, 0xE2], verbose=False)
time.sleep(speed)
def send_null():
while(True):
send_msg(0x81, start, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], verbose=False)
print('')
time.sleep(speed*2)
def send_random_pairs(id, index):
rand = randint(0, 65535) # 0x00 - 0xFF
rand_hex = bytearray(rand.to_bytes(2, 'big'))
data = [0x40, 0x8B, 0x02, 0x12, 0x18, 0x05, 0xC0, 0xE2]
data[index] = rand_hex[0]
send_msg(id, start, data)
print(' - {}'.format(rand_hex[0]))
'''
Generates a random byte from 0x00 to 0xFF in order
Pass a tuple index to modify the sample data to the random byte for a brute force method of determining what the code does
'''
def send_sequential_byte(index, can_ids, speed, data=[00,00,00,00,00,00,00,00]):
for x in range(0x00, 0xFF):
for id in can_ids:
data = data
for i in index:
data[i] = x
send_msg(id, start, data)
print(' - {}'.format(str(x)))
time.sleep(speed)
# m#erged bruteforce.py into here
'''
Similar to the above function, except this one will increment over multiple byte ranges.
So it will treat multiple bytes as one large number and increment it all together.
'''
def send_incremental_bytes(starting_index, starting_byte, num_bytes, can_ids, speed, data=[00,00,00,00,00,00,00,00]):
min = starting_byte
max = int('0x' + ('FF' * num_bytes), 16)
for x in range(min, max):
new_bytes = x.to_bytes(num_bytes, 'big')
for id in can_ids:
for i in range(len(new_bytes)):
data[i + (starting_index)] = new_bytes[i] # replace bytes
send_msg(id, start, data)
print(' - {}'.format(str(x)))
time.sleep(speed)
# this method allows us to also run the brute force commands but still use arrows
# this way I can start experimenting with digital gauges such as oil pressure or air/fuel ratio
def brute_force():
while(True):
#send_sequential_byte(seq_bytes, can_ids, 00.16, sample_data)
send_incremental_bytes(
starting_index=1 , #0 tart
starting_byte = 0x006572,
num_bytes= 3, # 1 start
can_ids=can_ids,
speed=0.16,
data=sample_data
)
def send_0x5__series():
x5xx_SERIES_1 = 0x581
x5xx_SERIES_2 = 0x596
x5xx_SERIES_3 = 0x59E
x5xx_SERIES_4 = 0x5B3
x5xx_SERIES_5 = 0x5B5
# not sure what these do but since they seem to be hard coded, gonna send them
send_msg(x5xx_SERIES_1, start, [0x81, 00, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
send_msg(x5xx_SERIES_2, start, [0x96, 00, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
send_msg(x5xx_SERIES_3, start, [0x9E, 00, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
send_msg(x5xx_SERIES_4, start, [0xB3, 00, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
send_msg(x5xx_SERIES_5, start, [0xB5, 00, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF])
def keys():
listener = keyboard.Listener(on_press=on_press)
listener.start() # start to listen on a separate thread
listener.join() # remove if main thread is polling self.keys
pool = Pool(5)
pool.apply_async(send_on) # send the 0x3B3 on command
pool.apply_async(send_null) # send a blank version of 0x81
pool.apply_async(keys) # send whatever key is pressed to send to the cluster.
pool.apply_async(brute_force) # test out our brute force data, comment this out if not needed
#pool.apply_async(send_0x5__series)
pool.close()
pool.join()