在这个项目中,我使用 Beaglebone Blue 通过 OBDII 端口将其连接到车辆上的 CAN 总线。我展示了如何使用 can-utils 和 python-can 来发送和接收 CAN 消息。我还介绍了如何将 GPS 模块和蜂窝调制解调器连接到 Beaglebone,以便您可以远程获取数据并将数据发送到移动的汽车。我使用 Python 脚本收集 GPS 坐标并解码 CAN 消息(车速、发动机、RPM、温度等),然后将所有内容发送到在 AWS 上运行的简单 Flask 服务器。
我们今天正在构建的间谍设备称为 ChupaCarBrah。
这些是用于构建 ChupaCarBrah 的部件。
我使用塑料冲洗装置盖板连接 Beaglebone,并使用橡皮筋固定其他部件。我不得不在盖板的侧面钻两个额外的孔以匹配 BeagleBone 孔。我建议使用彩色连接线。这里使用的颜色标准是:
BeagleBone 引脚和 CAN 连接器如下所示。需要一个 JST/SH 连接器将连接线连接到 BeagleBone CAN 插槽。
将 JST/SH 连接器连接到 Beaglebone Blue 上的 CAN 插槽,如下所示
将您的连接线连接到母连接器。在我们的例子中,连接器具有以下标准: 黑色:GND;红色:不会使用;黄色:CAN Hi;白色:CAN lo。你的可能不一样。
将黑色连接线的末端连接到 DC Barrel Jack 适配器上的负极“-”插槽,但先不要拧紧。获取另一根黑色连接线并插入同一个“-”插槽。将两根黑线拧在一起。
将红色连接线连接到 DC Barrel Jack 适配器上的正极“+”插槽。
DC Barrel Jack Adapter 插入 Beaglebone 12V 输入插孔。OBDII 将提供为 BeagleBone 供电所需的 12V。
将连接线连接到母 OBDII 连接器。您可能需要查看车辆手册,但通常 OBDII 的标准引脚是:
根据我们的连接线颜色代码约定,您需要将黑色线连接到 OBDII pin5;黄线到pin6;绿线接pin14,红线接pin 16。
此时您已经有了一个可以通过 OBDII 与您的汽车 CAN 总线交互的功能设备。如果这就是您要查找的全部内容,请跳至“带有 can-utils 的 CAN 总线”部分。
要构建完整的 ChupaCarBrah 设备,您仍然需要添加 GPS 模块、蜂窝调制解调器和电池。电池是可选的,但在您的汽车电池没电或 OBDII 电源断开的情况下非常重要(即使电池完全没电,您也可以找到您的车辆)。
将 GPS 模块连接到 BeagleBone 上的 UART GPS 插槽。
将您的 USB 蜂窝调制解调器连接到 BeagleBone 上的 USB 端口。在将蜂窝调制解调器连接到 BeagleBone 之前,请确保您已将有效的 SIM 卡插入到蜂窝调制解调器。
将 BeagleBone 连接到塑料板或您选择的任何其他绝缘材料上。
确保 GPS 模块和电池正确放置在底部。
将 OBDII 电缆放在电池上并使用橡皮筋固定所有东西。
确保连接线固定在 OBDII 连接器上。我也用了更多的橡皮筋。
连接电池,您的 ChupaCarBrah 将启动。
现在您已经准备好硬件,让我们设置所有必要的软件,以便我们可以开始使用 CAN 消息。
打开您的 BeagleBone 并通过 WiFi 连接到它。我建议仅在长距离上使用蜂窝 LTE 网络,以便为您的数据计划节省一些钱。确保你已经安装并更新了 can-utils/socketCAN。运行以下命令:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install can-utils
安装/更新 can-utils 后,检查 can0 接口是否可用
sudo ifconfig can0
root@beaglebone:~# sudo ifconfig can0
can0: flags=128 mtu 16
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 43
如果您在第二行看到带有 的类似输出,则表示您的 can0 接口可用且已禁用。在将 ChupaCarbrah 连接到汽车之前,您希望将其关闭。如果您需要禁用它,请运行:
sudo ifconfig can0 down
然后再次检查状态
sudo ifconfig can0
在确认接口 can0 可用和禁用后,将 ChupaCarBrah 连接到您的汽车 OBDII 端口(又名 DLC - 数据链路连接器)。有关确切位置,请参阅您的汽车手册,但通常位于靠近方向盘的仪表板下方。
完成整个设置后,您可能希望将其隐藏在仪表板中。
将 ChupaCarBrah 物理连接到您的汽车后,打开点火钥匙。您可能想启动引擎以防止耗尽汽车的电池(不要犯我犯的同样错误)。设置波特率,在我们的例子中是 500kbps,然后打开 can0 接口:
sudo ip link set can0 up type can bitrate 500000
sudo ifconfig can0 up
sudo ifconfig can0
root@beaglebone:~# sudo ifconfig can0
can0: flags=193 mtu 16,running,noarp>
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 10 (UNSPEC)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 43
如您所见,现在输出包含“”,这意味着您已准备好发送一些 CAN 消息。,>打开另一个终端(ssh 会话)并运行:
sudo candump can0
根据您的车辆,您可能会看到很多消息被捕获,类似于以下内容:
can0 418 [8] 50 FF 60 00 00 20 00 00
can0 412 [6] 1E 00 7A 00 8E 00
can0 2F1 [8] 00 00 79 00 00 00 00 00
can0 300 [8] 00 1B 80 89 9F FF 80 0A
can0 248 [8] 00 08 00 09 00 00 41 01
can0 236 [8] 0F FF 10 00 F0 00 00 39
can0 328 [8] 00 00 80 00 D8 80 FF FF
can0 330 [8] 0C FC FC FF FF FF 3F 89
can0 210 [8] 00 00 00 00 00 00 00 00
can0 308 [8] 40 02 B0 40 01 1F FF 00
can0 309 [7] 1F FF FF FF 0F FF 00
can0 312 [8] 67 EF 07 EF 09 BF 07 92
can0 356 [7] 3F FF 3F FF 0B B8 00
can0 7BC [8] 40 00 00 00 00 00 00 00
can0 218 [8] 8E 38 DD 42 00 80 00 00
can0 338 [8] FF FF 00 FF FF 00 FF FF
can0 315 [7] 28 00 00 00 00 8D 00
can0 200 [8] 00 03 C0 00 C0 00 C0 00
但是,对于某些车辆,包括我的车辆,ODBII CAN 总线默认是安静的,并且只会对发送到总线的消息做出反应。如果您也是这种情况,您可以通过使用“cansend”命令发送检索车辆 VIN 号的消息来确认 CAN 是否正常工作。让“candump”在第二个终端上运行并返回到第一个终端。然后运行:
sudo cansend can0 7DF#0209020000000000
在运行“candump”的终端上,您应该能够看到与此类似的请求和响应:
root@beaglebone:~# candump can0
can0 7DF [8] 02 09 02 00 00 00 00 00
can0 7E8 [8] 10 14 49 02 01 32 43 34
can0 484 [8] 03 7F 09 11 00 00 00 00
第二行的响应“7E8”将最后 3 个字节设置为 32 43 34。如果我们将其从十六进制解码为 ASCII,我们会得到“2C4”,这实际上是我的车辆 VIN 的前 3 个数字。
您可以使用此在线 VIN 解码器来确认数据是否准确:https ://vpic.nhtsa.dot.gov/decoder/Decoder
为获取 VIN 号码而发送的消息是“7DF#0209020000000000”。7DF 是 CAN 仲裁 ID(您想使用像这样的大数字进行测试,因为较高的数字具有较低的优先级)。“0209020000000000”是数据字段:
第一个“02”字节表示只有数据字段上接下来的两个字节是命令的一部分。剩余的“00”字节全部被忽略;
如果您想尝试手动发送其他命令,请参考:https ://en.wikipedia.org/wiki/OBD-II_PIDs
现在您确认 can-utils 工作正常,让我们使用 Python 发送更多命令。首先,确保您安装了 python-can pip 模块:
sudo python3 -m pip install python-can
然后,运行get_vin.py以检索您汽车的 VIN。这是get_vin.py的 Python 代码:
import can
bus = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000)
service_int = 9
pid_int = 2
msg = can.Message(arbitration_id=0x7DF, data=[2, service_int, pid_int, 0, 0, 0, 0, 0], is_extended_id=False)
try:
bus.send(msg)
response = bus.recv(timeout=2)
print(response)
except can.CanError:
print("CAN error")
finally:
bus.shutdown()
sudo python3 get_vin.py
随意更改“ service_int ”和“ pid_int ”的值并测试OBDII PID 文档中的其他命令。
要测试您的 GPS 模块,只需运行:
tio /dev/ttyO2 -b 4800
你应该得到一个类似这样的数据流:
root@beaglebone:~# tio /dev/ttyO2 -b 4800
[tio 17:04:53] tio v1.32
[tio 17:04:53] Press ctrl-t q to quit
[tio 17:04:53] Connected
$GPGGA,170454.000,3500.87097,N,10641.14163,W,1,08,1.1,204.3,M,-34.0,M,,0000*69
$GPGSA,A,3,30,07,11,28,01,08,17,13,,,,,2.2,1.1,2.0*33
$GPRMC,170454.000,A,3500.87097,N,10641.14163,W,0.00,171.40,100520,,,A*79
$GPGGA,170455.000,3500.87097,N,10641.14163,W,1,08,1.1,204.3,M,-34.0,M,,0000*68
$GPGSA,A,3,30,07,11,28,01,08,17,13,,,,,2.2,1.1,2.0*33
$GPGSV,3,1,12,30,74,271,37,07,62,163,35,11,51,074,37,28,46,294,18*74
$GPGSV,3,2,12,01,41,120,31,08,30,049,31,17,26,226,27,13,23,302,28*73
$GPGSV,3,3,12,15,04,323,14,23,16,208,,19,03,224,,09,00,189,*77
$GPRMC,170455.000,A,3500.87097,N,10641.14163,W,0.00,171.40,100520,,,A*78
$GPGGA,170456.000,3500.87097,N,10641.14163,W,1,08,1.1,204.3,M,-34.0,M,,0000*6B
$GPGSA,A,3,30,07,11,28,01,08,17,13,,,,,2.2,1.1,2.0*33
$GPRMC,170456.000,A,3500.87097,N,10641.14163,W,0.00,171.40,100520,,,A*7B
[tio 17:04:56] Disconnected
按“ctrl-t q”退出。您的位置将在句子“GPRMC”上可用。例如,复制句子“ $GPRMC, 170454.000, A, 3500.87097, N, 10641.14163, W, 0.00, 171.40, 100520,,, A*79 ”并使用此在线解码器对其进行解码:https ://rl.se/ gprmc
放大地图,看看 GPS 数据有多准确。
现在,让我们使用 Python 做同样的事情。确保您已安装 pyserial 模块:
sudo python3 -m pip install pyserial
然后,运行get_gps_data.py以检索您汽车的位置。这是get_gps_data.py 的 Python 代码:
import time
import serial
gps_data = ""
utf_data = ""
ser = serial.Serial('/dev/ttyO2', 4800)
counter = 0
while utf_data.find("GPRMC") == -1:
counter += 1
try:
ser_data = ser.readline()
utf_data = ser_data.decode()
except:
utf_data = ""
time.sleep(0.5)
if counter > 50:
break
ser.close()
if utf_data.find("GPRMC") != -1:
utf_data = utf_data.replace('\r', '')
utf_data = utf_data.replace('\n', '')
gps_data = utf_data
print(gps_data)
sudo python3 get_gps_data.py
root@beaglebone:~# sudo python3 get_gps_data.py
$GPRMC,173439.000,A,3500.87097,N,10641.14163,W,0.00,348.52,100520,,,A*74
下一步是创建蜂窝 LTE 数据链路,这样即使汽车不在我们的 WiFi 网络范围内,您也可以访问 GPS 和 CAN 数据。
在本教程中,我使用 USB Hologram.io蜂窝调制解调器。随意使用其他选项。我将使用 PPP 连接,因此 Python 客户端可以将数据发送到在 AWS 上运行的服务器应用程序。确保已安装 ppp,然后安装 hologram-python:
sudo apt-get install ppp
sudo python3 -m pip install hologram-python
您还需要订阅数据计划并激活您的 SIM 卡。请参阅官方全息图文档以准备好您的卡。
激活您的卡后,确保您的蓝色 LED 指示灯亮起,并且调制解调器上的红色 LED 指示灯闪烁。
然后,要连接和断开与蜂窝网络的连接,请运行:
sudo hologram network connect
sudo hologram network disconnect
为了测试 Internet 连接,您可以使用单个 ICMP 请求 ping Google:
ping -c 1 www.google.com
如果您收到回复,则表示 ChupaCarBrah 已连接到蜂窝网络,并且它应该能够在您在 LTE 覆盖范围内驾驶的任何地方(几乎在美国的任何地方)泄露汽车数据。
现在,让我们看看如何使用 Python 连接和断开 Hologram 蜂窝网络。运行cellular_test.py脚本来检查您的 LTE 数据与互联网的连接。这是示例脚本cellular_test.py 的 Python 代码:
import psutil
import time
import subprocess
from Hologram.CustomCloud import CustomCloud
def hologram_network_connect():
hologram_network_disconnect()
time.sleep(2)
cloud = CustomCloud(None, network='cellular')
cloud.network.disable_at_sockets_mode()
res = cloud.network.connect()
message = ""
if res:
message = "PPP session started"
else:
message = "Failed to start PPP"
print(message)
def hologram_network_disconnect():
print('Checking for existing PPP sessions')
for proc in psutil.process_iter():
try:
pinfo = proc.as_dict(attrs=['pid', 'name'])
except:
print("Failed to check for existing PPP sessions")
if 'pppd' in pinfo['name']:
print('Found existing PPP session on pid: %s' % pinfo['pid'])
print('Killing pid %s now' % pinfo['pid'])
process = psutil.Process(pinfo['pid'])
process.terminate()
process.wait()
hologram_network_connect()
time.sleep(2)
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "www.google.com"], stdout=subprocess.PIPE).stdout.read()
print(ping_response.decode())
time.sleep(2)
hologram_network_disconnect()
sudo python3 cellular_test.py
root@beaglebone:~# sudo python3 cellular_test.py
Checking for existing PPP sessions
PPP session started
PING www.google.com (216.58.201.228) 56(84) bytes of data.
64 bytes from par10s33-in-f4.1e100.net (216.58.201.228): icmp_seq=1 ttl=49 time=420 ms
--- www.google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 420.049/420.049/420.049/0.000 ms
Checking for existing PPP sessions
Found existing PPP session on pid: 1559
Killing pid 1559 now
现在您知道如何使用 Python 发送和接收 CAN 消息了;获取 GPS 位置;并连接到蜂窝网络;让我们把它们放在一起,创建一个简单的客户端和服务器应用程序来泄露所有数据。
我给你带来了两个非常简单的 Python 脚本,它们可以作为一个框架来构建更复杂的汽车黑客应用程序。客户端脚本基本上是我迄今为止介绍的所有示例 Python 脚本的组合。它将在 BeagleBone Blue 上运行。服务器脚本是一个简单的 Flask 应用程序,它将在 AWS(Elastic Beanstalk)上运行,并将使用 JSON 格式存储和显示所有泄露的数据。
客户端脚本 - chupacarbrah.py
chupacarbrah.py客户端脚本可以在这里找到。使用以下 git 命令将其克隆到您的 BeagleBone:
git clone https://github.com/blupants/chupacarbrah.git
cd chupacarbrah
客户端脚本从由变量“ obd2_csv_file ”定义的 csv 文件中读取要执行的 OBDII PID 命令列表。然后它解析命令以创建 CAN 消息。csv 文件格式包括一个“启用”列,允许您启用(设置为 1)或禁用(设置为零)您要执行的特定 OBDII PID。默认情况下,脚本使用simple.csv文件和以下命令子集:
文件obd2_std_PIDs_enabled.csv包含要启用/禁用的所有可用 OBDII PID 命令。请确保您了解这些命令的作用,并在启用额外命令之前知道您在做什么。
chupacarbrah.py 客户端脚本将使用 csv 文件中的 OBDII PID 公式解码所有响应,并将数据与 GPS 坐标一起发布到 AWS 上的 Flask 应用程序。确保在变量“ server_url ”上定义服务器 URL 。我们将很快介绍如何将服务器脚本部署到 AWS 以及如何获取服务器 URL。
正确配置客户端应用程序后,您可以运行它:
sudo python3 chupacarbrah.py
它将显示从 CAN 响应消息中解码的当前数据,并每 1 分钟将所有内容发送到服务器。
要停止客户端并正常退出,请运行:
sudo touch /tmp/stop
现在,让我们设置服务器脚本来接收泄露的数据。
服务器脚本 - chupacarbrah_server.py
chupacarbrah_server.py脚本可以在这里找到。它将公开两个端点,以便您可以发送和获取泄露的数据:
发布 /api/v1/汽车
获取 /api/v1/状态
客户端脚本将使用“POST /api/v1/cars”端点提交所有数据。然后,您可以在家中舒适地使用“GET /api/v1/status”从 Web 浏览器监控 JSON 数据。
让我们设置一个简单的本地 Flask 应用程序并在这两个端点上运行一些快速测试。在本教程的后面,我将展示如何将这个相同的本地应用程序部署到 AWS。
在您的本地 PC 上,而不是 BeagleBone,创建一个项目目录:
~$ mkdir eb-flask
~$ cd eb-flask
创建并激活一个名为“virt”的虚拟环境:
~/eb-flask$ virtualenv virt
~$ source virt/bin/activate
(virt) ~/eb-flask$
使用 pip install 安装烧瓶:
(virt)~/eb-flask$ pip install flask==1.0.2
使用 pip freeze 查看已安装的库:
(virt) sacchetin@Sacchetins-MacBook-Air eb-flask % pip freeze
aniso8601==8.0.0
click==7.1.2
Flask==1.0.2
Flask-RESTful==0.3.8
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
pytz==2020.1
six==1.14.0
Werkzeug==1.0.1
(virt) sacchetin@Sacchetins-MacBook-Air eb-flask %
将 pip freeze 的输出保存到名为 requirements.txt 的文件中。
(virt)~/eb-flask$ pip freeze > requirements.txt
将chupacarbrah_server.py下载到您的eb-flask文件夹并将其重命名为application.py:
curl "https://raw.githubusercontent.com/blupants/chupacarbrah_server/master/chupacarbrah_server.py" -o application.py
在本地运行应用程序进行测试:
(virt) sacchetin@Sacchetins-MacBook-Air eb-flask % python3 application.py
* Serving Flask app "application" (lazy loading)
* Environment: production
WARNING: Do not use the development server in a production environment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
发送一些虚拟数据以确保一切正常。打开一个新终端并使用 curl 发送一些数据:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"car_uuid":"51f317ec266e4adb956212201f87ba52", "VIN": "2C4", "maker": "Generic", "log":{"timestamp":"20200501120000","GPS":"00"}}' \
"http://localhost:5000/api/v1/cars"
本地服务器将回复 car_uuid,在本例中为:“51f317ec266e4adb956212201f87ba52”。打开浏览器,最好是 Firefox,因为它原生解析 JSON,然后访问http://localhost:5000/api/v1/status
如果您能够看到刚刚使用 curl 发布的虚拟数据,则意味着您的 Flask 应用程序已准备好部署到 AWS。
首先,您需要在 AWS 上创建一个帐户并在您的计算机上安装 AWS 客户端。请在此处创建您的 AWS 账户。部署应用程序所描述的步骤基于此处的官方AWS 文档。
确保您能够登录 AWS 控制台。然后,安装 AWS 客户端:
python3 -m pip install awscli
python3 -m pip install awsebcli
使用 eb init 命令初始化您的 EB CLI 存储库:
~/eb-flask$ eb init -p python-3.6 flask-chupacarbrah --region us-east-2
可选,但强烈建议:再次运行 eb init 以配置默认密钥对,以便您可以使用 SSH 连接到运行您的应用程序的 EC2 实例:
~/eb-flask$ eb init
Do you want to set up SSH for your instances? (y/n): ySelect a keypair. 1) my-keypair 2) [ Create new KeyPair ]
创建一个环境并使用 eb create 将您的应用程序部署到其中:
~/eb-flask$ eb create chupacarbrah-env
环境创建大约需要 5 分钟。环境创建过程完成后,使用 eb open 打开您的网站:
~/eb-flask$ eb open
它将打开一个网络浏览器并自动加载新服务的 URL。复制 URL,返回到您的 BeagleBone,编辑客户端脚本 chupacarbrah.py 并将变量“ server_url ”更改为您的 AWS 应用程序的实际 URL。使用我的部署示例,“ server_url ”的值应设置为:
global server_url
server_url = "http://chupacarbrah-env.eba-bdahj3wp.us-east-2.elasticbeanstalk.com/"
您的 URL 会有所不同,但格式应该相似。在 BeagleBone 上重新启动 chupacarbrah.py,从现在开始,它将开始向 AWS 发送数据。
您也可以将一些虚拟数据发送到您的 AWS 应用程序以进行测试。通过将 localhost:5000 替换为您设置变量“ server_url ”的相同值来重复“POST /api/v1/cars” curl 请求。例如:
curl --header "Content-Type: application/json" \
--request POST \
--data '{"car_uuid":"51f317ec266e4adb956212201f87ba52", "VIN": "2C4", "maker": "Generic", "log":{"timestamp":"20200501120000","GPS":"00"}}' \
"http://chupacarbrah-env.eba-bdahj3wp.us-east-2.elasticbeanstalk.com/api/v1/cars"
打开 Firefox 浏览器并再次访问http://chupacarbrah-env.eba-bdahj3wp.us-east-2.elasticbeanstalk.com/ 。您应该会看到您发送的所有虚拟数据以及从 ChupaCarBrah 设备中提取的所有数据。
我目前正在撰写一系列关于汽车黑客攻击的网络安全文章。请继续关注我的Medium 页面,了解更多关于您今天刚刚构建的 ChupaCarBrah 设备可以做的所有事情。
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !