使用虚拟机连接西门子PLC并构建socket向其发送数据包

最近在做工业控制网络的模糊测试的实验环境配置时遇到了一些问题,在一番搜索解决问题后打算把验环境配置过程记录下来。

一、实验设备

PLC:SIMATIC S7-200 SMART
软件:STEP 7-MicroWIN SMART
虚拟机:kali Linux

二、环境配置

1.连接PLC

首先使用网线连接PLC与电脑主机,修改主机IP地址使其与目标PLC在同一网段,如下图:(本文所使用PLC为固定IP,网段为192.168.2.X)
在这里插入图片描述
打开S7MicroWIN SMART软件,点击通信图标
在这里插入图片描述
通信接口选择当前主机的以太网卡,
在这里插入图片描述
点击查找CPU就可以找到当前已连接的PLC设备,此时点击闪烁指示灯就可以观察到PLC的指示灯闪烁。如果在这一步通信接口下拉选项为空白,打开主机的服务选项,确保以下服务处于打开状态
在这里插入图片描述
点击RUN按钮将PLC置于run模式

1.虚拟机配置

虚拟机选用桥接模式,也要把IP地址设置为和PLC在同一网段
在这里插入图片描述

socket代码如下(示例):

#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
 
#define SERVER_PORT 502  //PLC目标端口号 
 
 
int main()
{
    //客户端只需要一个套接字文件描述符,用于和服务器通信
	int clientSocket;
    //描述服务器的socket
	struct sockaddr_in serverAddr;

	char recvbuf[200];
	int iDataNum;
	if((clientSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
	{
		perror("socket");
		return 1;
	}
 
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(SERVER_PORT);
	
    //inet_addr()函数,将点分十进制IP转换成网络字节序IP
	serverAddr.sin_addr.s_addr = inet_addr("192.168.2.1");
	if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0)
	{
		perror("connect");
		return 1;
	}
 
	printf("connect with destination host...\n");

    //open dataflow file 
	FILE * pFile;
	pFile = fopen ("/root/Public/dataflow.txt","r");
	if (pFile == NULL)
		perror ("Error opening file");
	else {
		while( !feof(pFile) ){
		
			char tcp_send_data[31] = {};
			char ch[30]={};
			fgets(ch,100,pFile);
			printf("%s", ch);

			int data_size = 0;
			for(int i=0,p=0;p<strlen(ch)/2;i=i+2,p++){
				//TODO
				int k=0,j=0;
				if(ch[i]>='0'&&ch[i]<='9'){				
					k=ch[i]-'0' ;				
				}else{				
					k=ch[i]-'a' +10;
				}
				if(ch[i+1]>='0'&&ch[i+1]<='9'){				
					j=ch[i+1]-'0';				
				}else{
			
					j=ch[i+1]-'a' +10;				
				}	
				 k=k<<4; 
				unsigned char a=j +k;
				tcp_send_data[p]=a;
				data_size = p;
			}
			
			send(clientSocket, tcp_send_data, data_size, 0);    //发送数据包 
	
//			iDataNum = recv(clientSocket, recvbuf, 200, 0);
//			recvbuf[iDataNum] = '\0';
//			printf("recv data of my world is: %s\n", recvbuf);

			sleep(1);
		}
	}
	close(clientSocket);
	return 0;
}

在虚拟机端运行socket程序,即可实现向目标PLC发送数据包

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值