OBD数据分析(三)

OBD数据分析(三)——将数据按照特征分类

  • 处理数据
    • 将数据分为4段,分别为A、B、C、D
    • 分析数据,选出有特征的id数据
  • 进行检测
    • 对具体内容的大小进行检测分析是否有入侵
    • 对速度进行检测,若速度变化在一定范围内则无入侵
    • 将一些数据加入白名单

处理数据

将数据分为4段,分别为A、B、C、D

删除相同数据内容的数据后,处理数据

  • 有些数据内容一直保持不变,则合并为一条数据
  • 有些数据一直变化,则取其平均值

处理结果如下:
OBD数据分析(三)_第1张图片

分析数据,选出有特征的id数据

分析发现,某些数据如下图所示,数据内容始终保持为0000 0000 0000 0000,或DLC一直为0:
OBD数据分析(三)_第2张图片

进行检测

对具体内容的大小进行检测分析是否有入侵

将消息的具体内容分为了四个部分,如下所示,分别命名为A,B,C,D

class message
{
	public: 
	string Timestamp;
	string timestamp;
	string Id;
	string iD;
	string id;
	string DLc;
	string dlc;
	string A;
	string Aa;
	string B;
	string Ba;
	string C;
	string Ca;
	string D;
	string Da;
};

进过观察可知,某些数据,如id为02200000的消息,虽然内容在一直变化,但DLC始终未8,选取较中间大小的数据c603 f103 0c00 3f10,一部分消息就能被检测到攻击(因为数据是合理的,所以假设攻击),如下图所示
OBD数据分析(三)_第3张图片
故我们定义个规则集,用于检查在处理消息之前ECU应接受或拒绝的消息结构及其属性,如下所示

		if (mes.iD == "0220000")
		{
		//观察发现消息0220000的DLC一般为8,所以这里设不为8时为有入侵
		//通过对消息0220000的具体内容进行分析,得四个信号的最大值分别是 c6 03 f1 03 0c 00 3f 10
		//即超过这四个信号的最大值是判断为有入侵 
			if(mes.dlc != "8" || mes.A > "c603" || mes.B > "f103" || mes.C > "0c00" || mes.D > "3f10")
			{
				cout << "MALFORMED FRAME with ID " << mes.iD <<endl;
			}
			else
			{
				cout << mes.iD << "it is a safe id number!" << endl;
			}
		}

执行结果如图
OBD数据分析(三)_第4张图片
完整代码如下

//手头的消息进行分析,我们将消息分为四个信号,分别为abcd,均最都具有两位 
//之后,定义了一个规则集,用于检查在处理消息之前ECU应接受或拒绝的消息结构及其属性。 
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
class message
{
	public: 
	string Timestamp;
	string timestamp;
	string Id;
	string iD;
	string id;
	string DLc;
	string dlc;
	string A;
	string Aa;
	string B;
	string Ba;
	string C;
	string Ca;
	string D;
	string Da;
};
int main()
{
//0220000 c6 03 f1 03 0c 00 3f 10
    std::vector<message> set;
	ifstream In("F:\\DoS_attack_dataset.txt");
	string line;	
	string id[10];
		
	while(getline(In,line))//逐行读取数据并存于line中,直至数据全部读取
	{
		message mes;
        std::stringstream input(line);
		input >> mes.Timestamp >> mes.timestamp >> mes.Id >> mes.iD >> mes.id >> mes.DLc >> mes.dlc >> mes.A >> mes.Aa >> mes.B >> mes.Ba >> mes.C >> mes.Ca >> mes.D >> mes.Da;
		
		mes.iD += mes.id;
		mes.A += mes.Aa;
		mes.B += mes.Ba;
		mes.C += mes.Ca;
		mes.D += mes.Da;
		cout << mes.iD <<endl;
			
		if (mes.iD == "0220000")
		{
		//观察发现消息0220000的DLC一般为8,所以这里设不为8时为有入侵
		//通过对消息0220000的具体内容进行分析,得四个信号的最大值分别是 c6 03 f1 03 0c 00 3f 10
		//即超过这四个信号的最大值是判断为有入侵 
			if(mes.dlc != "8" || mes.A > "c603" || mes.B > "f103" || mes.C > "0c00" || mes.D > "3f10")
			{
				cout << "MALFORMED FRAME with ID " << mes.iD <<endl;
			}
			else
			{
				cout << mes.iD << "it is a safe id number!" << endl;
			}
		}
	}
	return 0;
} 

对速度进行检测,若速度变化在一定范围内则无入侵

  • 通过查阅论文知道,每条消息的具体内容都与某个具有现实意义的描述(如速度,汽油温度等)存在函数关系。
  • 分析我们手头的数据,我们假设此时汽车速度增加大小保持在一定的数据上下浮动,故选择数据变化较有规律的消息,定义ID为0080000具体内容大致如下:
    OBD数据分析(三)_第5张图片
  • 定义mes.CarSpeed = mes.C (其中mes.C是上图中圈起来的数据)
  • 定义阈值为300(因为数据是正常数据,所以我们假设阈值为300时是受到了攻击),即速度-原速度超过阈值则判断为有攻击
    运行结果如下所示
  • 安全消息
    OBD数据分析(三)_第6张图片
  • 有攻击
    OBD数据分析(三)_第7张图片
    完整代码如下
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <cmath>
using namespace std;
class message
{
	public: 
	string Timestamp;
	string timestamp;
	string Id;
	string iD;
	string id;
	string DLc;
	string dlc;
	string A;
	string Aa;
	string B;
	string Ba;
	string C;
	string Ca;
	string D;
	string Da;
	string CarSpeed;
};
int main()
{
    std::vector<message> set;
	ifstream In("F:\\DoS_attack_dataset.txt");
	string line;	
	string id[10];
		
	while(getline(In,line))//逐行读取数据并存于line中,直至数据全部读取
	{
		message mes;
        std::stringstream input(line);
		input >> mes.Timestamp >> mes.timestamp >> mes.Id >> mes.iD >> mes.id >> mes.DLc >> mes.dlc >> mes.A >> mes.Aa >> mes.B >> mes.Ba >> mes.C >> mes.Ca >> mes.D >> mes.Da;
		
		mes.iD += mes.id;
		mes.A += mes.Aa;
		mes.B += mes.Ba;
		mes.C += mes.Ca;
		mes.D += mes.Da;
		cout << mes.iD <<endl;
		
		int carspeed_monitor = 0;//现在的速度与之前的速度的差值 
		int speed_diff_threshold = 300;//定义阈值,现速度-原速度超过阈值则判断为有攻击 
		string previous_speed = "1511";//先假定之前的速度为1511
		mes.CarSpeed = mes.C;
		if(mes.iD == "0080000")
		{
			carspeed_monitor = atoi(mes.CarSpeed.c_str()) - atoi(previous_speed.c_str());
			previous_speed = mes.CarSpeed;
			if (abs(carspeed_monitor) >= speed_diff_threshold)
			{
				cout << "FALSE READINGS" <<endl;
			}
			else
			{
				cout << mes.iD << "it is a safe id number!" << endl;
			}
		}	
	}
	return 0;
} 

将一些数据加入白名单

  • 通过上文的分析知道,某些数据如下图所示,数据内容始终保持为0000 0000 0000 0000,或DLC一直为0:
    OBD数据分析(三)_第8张图片
    将这些数据加入白名单,没有在白名单的数据都会显示“Unauthorized message with ID=”了,结果如下
    OBD数据分析(三)_第9张图片
    完整代码如下
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <cmath>
using namespace std;
class message
{
	public: 
	string Timestamp;
	string timestamp;
	string Id;
	string iD;
	string id;
	string DLc;
	string dlc;
	string A;
	string Aa;
	string B;
	string Ba;
	string C;
	string Ca;
	string D;
	string Da;
	string CarSpeed;
};
int main()
{
    std::vector<message> set;
	ifstream In("F:\\DoS_attack_dataset.txt");
	string line;	
	string id[10];
		
	while(getline(In,line))//逐行读取数据并存于line中,直至数据全部读取
	{
		message mes;
        std::stringstream input(line);
		input >> mes.Timestamp >> mes.timestamp >> mes.Id >> mes.iD >> mes.id >> mes.DLc >> mes.dlc >> mes.A >> mes.Aa >> mes.B >> mes.Ba >> mes.C >> mes.Ca >> mes.D >> mes.Da;
		
		mes.iD += mes.id;
		mes.A += mes.Aa;
		mes.B += mes.Ba;
		mes.C += mes.Ca;
		mes.D += mes.Da;
		cout << mes.iD <<endl;
		
		string messages_allowed[15] = {"01f1000","04b0000","0034000","0510000","0517000","01f1100","05a2100","04b0100","05a2100","04b1100","0153100","0164100","0220100","0000000"};
		int i; 
		int count=0;
		for(i=0; i < 15; i++)
		{
			if(mes.iD == messages_allowed[i])
			{
				count++;
			}
		}
		if(count == 0)
		{
			cout << "Unauthorized message with ID=" << mes.iD <<endl;
		}
	
	}
	return 0;
} 

你可能感兴趣的:(OBD数据分析(三))