freeBuf
主站

分類

漏洞 工具 極客 Web安全 系統安全 網絡安全 無線安全 設備/客戶端安全 數據安全 安全管理 企業安全 工控安全

特色

頭條 人物志 活動 視頻 觀點 招聘 報告 資訊 區塊鏈安全 標準與合規 容器安全 公開課

官方公眾號企業安全新浪微博

FreeBuf.COM網絡安全行業門戶,每日發布專業的安全資訊、技術剖析。

FreeBuf+小程序

FreeBuf+小程序

工控安全 | 西門子通信協議S7COMM(Part 1)
2018-11-06 09:00:41

*本文原創作者:LiukerTeam,本文屬FreeBuf原創獎勵計劃文章,未經許可禁止轉載

隨著網絡強國、工業4.0,工控安全市場今年明顯有相當大的改善,無論從政策還是客戶需求,都在逐步擴大中。但是,搞工控安全研究的人員卻寥寥無幾,一方面,沒有可以研究和學習的便利的環境;另一方面工控安全是個跨學課的技術,需要了解多方面的知識,有比較高的技術上的門檻。特別是工控系統中通信協議,在工控系統中通信協議存在眾多標準,也存在眾多私有協議,如果你有過使用組態軟件的經歷,你便會發現,在第一步連接設備時除連接設備的方式有以太網/串行等方式外,各家基本上都存在自己的私有通信協議。比如:西門子的是S7Comm協議。

所以,本文主要介紹西門子的S7Comm協議(適用于S7-300、S7-400、S7-1200)。本文中S7Comm協議結構都是逆向而來,如有錯誤之處,請拍磚。

一、西門子PLC系統構成

在介紹西門子S7Comm協議,首先得明白西門子PLC的大概構造。雖然我們不必像專門編寫PLC程序員那樣。下圖1就是一個組態完畢的西門子S7 300的模型:

siemens-s7-300.jpg圖1 西門子S7-300

根據標號,各模塊分別是:

1.電源模塊(PS),供電專用

2.CPU模塊(CPU),負責處理信息

3.通信模塊(IM)

4.數字量輸入模塊(DI)

5.數字量輸出模塊(DO)

6.模擬量輸入模塊(AI)

7.模擬量輸出模塊(AO)

想具體了解的,請閱讀西門子S7-300教程 第2章。

二、S7協議結構

S7Comm(S7 Communication)是西門子專有的協議,是西門子S7通訊協議簇里的一種。

S7協議的TCP/IP實現依賴于面向塊的ISO傳輸服務。S7協議被封裝在TPKT和ISO-COTP協議中,這使得PDU(協議數據單元)能夠通過TCP傳送。

它用于PLC編程,在PLC之間交換數據,從SCADA(監控和數據采集)系統訪問PLC數據以及診斷目的。

S7Comm以太網協議基于OSI模型:

OSI layer Protocol
7 Application Layer S7 communication
6 Presentation Layer S7 communication (COTP)
5 Session Layer S7 communication (TPKT)
4 Transport Layer ISO-on-TCP (RFC 1006)
3 Network Layer IP
2 Data Link Layer Ethernet
1 Physical Layer Ethernet

其中,第1-4層會由計算機自己完成(底層驅動程序),關于這些神馬的定義,大家可以上網查一下;

第5層TPKT,應用程數據傳輸協議,介于TCP和COTP協議之間。這是一個傳輸服務協議,主要用來在COTP和TCP之間建立橋梁;

第6層COTP,按照維基百科的解釋,COTP 是 OSI 7層協議定義的位于TCP之上的協議。COTP 以“Packet”為基本單位來傳輸數據,這樣接收方會得到與發送方具有相同邊界的數據;

第7層,S7 communication,這一層和用戶數據相關,對PLC數據的讀取報文在這里完成。

可能會對TPKT和COPT迷惑,其實在具體的報文中,TPKT的作用是包含用戶協議(5~7層)的數據長度(字節數);COTP的作用是定義了數據傳輸的基本單位(在S7Comm中 PDU TYPE:DT data)。

s7comm-osi.png

圖2?S7Comm協議OSI模型

三、TPKT協議

TPKT協議是應用程數據傳輸協議,介于TCP和COTP協議之間。這是一個傳輸服務協議,主要用來在COTP和TCP之間建立橋梁。

其英文介紹如下:

TPKT is an "encapsulation" protocol. It carries the OSI packet in its own packet's data payload and then passes the resulting structure to TCP, from then on, the packet is processed as a TCP/IP packet. The OSI programs passing data to TPKT are unaware that their data will be carried over TCP/IP because TPKT emulates the OSI protocol Transport Service Access Point(TSAP).

TPKT結構如圖3:

tptk-structure.png

圖3 TPKT協議結構

其中,TPKT的結構為:

0 (Unsigned integer, 1 byte): Version,版本信息。

1 (Unsigned integer, 1 byte): Reserved,保留(值為0x00)。

2-3 (Unsigned integer, 2 bytes): Length,TPKT、COTP、S7三層協議的總長度,也就是TCP的payload的長度。

舉個例子,如圖4所示:

tpkt-example.jpg

圖4 一個TPKT的例子

從圖4中可知,其version=3,length=25(0x0019)。

四、COTP協議

COTP(ISO 8073/X.224 COTP Connection-Oriented Transport Protocol)是OSI 7層協議定義的位于TCP之上的協議。COTP以“Packet”為基本單位來傳輸數據,這樣接收方會得到與發送方具有相同邊界的數據。

COTP協議分為兩種形態,分別是COTP連接包(COTP Connection Packet)和COTP功能包(COTP Fuction Packet)。

4.1?COTP Connection Packet

COTP連接包(COTP Connection Packet)也就是S7Comm的握手包,其格式如圖5所示。

cotp-connection-structure.png

圖5?COTP連接包的結構

其中,?COTP連接包的頭結構為:

0 (Unsigned integer, 1 byte): Length,COTP后續數據的長度(注意:長度不包含length的長度),一般為17 bytes。

1 (Unsigned integer, 1 byte):?PDU typ,類型有:

0x1:?ED Expedited Data,加急數據

0x2:?EA Expedited Data Acknowledgement,加急數據確認

0x4:?UD,用戶數據

0x5:?RJ Reject,拒絕

0x6:?AK Data Acknowledgement,數據確認

0x7:?ER TPDU Error,TPDU錯誤

0x8:?DR Disconnect Request,斷開請求

0xC:?DC Disconnect Confirm,斷開確認

0xD:?CC Connect Confirm,連接確認

0xE:?CR Connect Request,連接請求

0xF:?DT Data,數據傳輸

2~3 (Unsigned integer, 2 bytes):?Destination reference.

4~5 (Unsigned integer, 2 bytes):?Source reference.

6 (1 byte):?opt,其中包括Extended formats、No explicit flow control,值都是Boolean類型。

7~? (length-7?bytes, 一般為11 bytes):?Parameter,參數。一般參數包含Parameter code(Unsigned integer, 1 byte)、Parameter length(Unsigned integer, 1 byte)、Parameter data三部分。

算了,還是來個例子,更加明了:

cotp-connection-request.jpg

圖6 連接請求包

圖6中,PDU類型為連接請求(0x0e),表示該數據包是一個連接請求包。為了更好對比,圖7為圖6的連接請求的響應包:

cotp-connection-confirm.jpg

圖7?連接確認包

4.2?COTP Fuction Packet

相對而言,COTP Fuction Packet比COTP Connection Packet簡單多了,其結構如圖8所示:

cotp-fuction-structure.png

圖8?COTP功能包的格式

其中,?COTPP功能包的頭結構為:

0 (Unsigned integer, 1 byte):?Length,COTP后續數據的長度(注意:長度不包含length的長度),一般為2 bytes。

1 (Unsigned integer, 1 byte):?PDU type,類型有:

0x1:?ED Expedited Data,加急數據

0x2:?EA Expedited Data Acknowledgement,加急數據確認

0x4:?UD,用戶數據

0x5:?RJ Reject,拒絕

0x6:?AK Data Acknowledgement,數據確認

0x7:?ER TPDU Error,TPDU錯誤

0x8:?DR Disconnect Request,斷開請求

0xC:?DC Disconnect Confirm,斷開確認

0xD:?CC Connect Confirm,連接確認

0xE:?CR Connect Request,連接請求

0xF:?DT Data,數據傳輸

2 (1 byte):?opt,其中包括Extended formats、No explicit flow control,值都是Boolean類型。

舉個例子,如圖9所示:

cotp-dt-data.jpg

圖9 數據傳輸包

上圖中,PDU類型為連接請求(0x0f),表示該數據包是一個數據傳輸的包。

OK,COTP的兩中結構介紹完了,接下來的S7Comm協議才是本文的重點。

五、S7Comm協議

上面,介紹了TPKT和COTP協議,現在開始介紹S7Comm協議,Are u ready?

S7Comm數據作為COTP數據包的有效載荷,第一個字節總是0x32作為協議標識符。

S7Comm協議包含三部分:

Header

Parameter

Data

s7comm-structure.png

圖10 S7Comm協議結構

根據實現的功能不同,S7 comm協議的結構會有所不同。

5.1?S7Comm Header

S7Comm的頭,定義了該包的類型、參數長度、數據長度等,其結構如圖11所示:

s7comm-header-structure.png

圖11 S7Comm Header結構

所以,S7Comm Header的格式為:

0 (unsigned integer, 1 byte): Protocol Id,協議ID,通常為0x32;

1 (unsigned integer, 1 byte): ROSCTR,PDU type,PDU的類型,一般有以下值:

0x01 - JOB(Request: job with acknowledgement):作業請求。由主設備發送的請求(例如,讀/寫存儲器,讀/寫塊,啟動/停止設備,設置通信);

0x02 - ACK(acknowledgement without additional field):確認響應,沒有數據的簡單確認(未遇到過由S7 300/400設備發送得);

0x03 - ACK_DATA(Response: acknowledgement with additional field):確認數據響應,這個一般都是響應JOB的請求;

0x07 - USERDATA:原始協議的擴展,參數字段包含請求/響應ID(用于編程/調試,讀取SZL,安全功能,時間設置,循環讀取...)。

2~3 (unsigned integer, 2 bytes): Redundancy Identification (Reserved),冗余數據,通常為0x0000;

4~5 (unsigned integer, 2 bytes): Protocol Data Unit Reference,it's increased by request event。協議數據單元參考,通過請求事件增加;

6~7 (unsigned integer, 2 bytes): Parameter length,the total length (bytes) of parameter part。參數的總長度;

8~9 (unsigned integer, 2 bytes): Data length,數據長度。如果讀取PLC內部數據,此處為0x0000;對于其他功能,則為Data部分的數據長度;

來看一個例子解釋一下,如圖12所示:

s7comm-header-1.jpg

圖12 一個S7Comm頭結構的例子

其中最重要的字段就是ROSCTR,它決定了后續參數的結構,這個后面的章節中有詳細的介紹。

在響應數據包中,還有可能存在錯誤信息。就拿圖12為例,如果出錯了,其響應包如圖13所示:

s7comm-header-2.jpg

圖13 帶有錯誤信息的響應包

其錯誤信息結構為:

10 (unsigned integer, 1 bytes): Error class,錯誤類型:

其詳細的Error class,參考6.1.1 頭結構的錯誤類型;

11 (unsigned integer, 1 bytes): Error code,錯誤代碼;

由此,可見圖13的錯誤類型是No error,至于錯誤代碼,啥含義我也母知道。

為了更好理解,接下來就不按照Parameter、Data的順序介紹,而是按照PDU類型進行介紹,尿急的趕緊上廁所哈!

5.2 作業請求(Job)和確認數據響應(Ack_Data)

上面介紹了S7Comm PDU的結構和通用協議頭其頭部結構。

S7Comm中Job和Ack_Data中的Parameter項的第一個字段是function(功能碼),其類型為Unsigned integer,大小為1 byte,其詳細的功能碼,請參考6.2.1 Job和Ack_Data的功能碼。決定了其余字段的結構、消息的目的。

所以接下來,將進一步介紹各功能碼對應的結構和作用。

5.2.1?建立通信(Setup communication [0xF0])

建立通信在每個會話開始時被發送,然后可以交換任何其他消息。它用于協商ACK隊列的大小和最大PDU長度,雙方聲明它們的支持值。ACK隊列的長度決定了可以同時啟動而不需要確認的并行作業的數量。PDU和隊列長度字段都是大端。

先說Job吧!當PDU類型為Job時,建立通信功能中Parameter的結構,如下圖:

s7comm-setup-communication-job.png

圖14?S7comm的結構(建立通信的作業請求)

具體的Parameter結構,如下:

1 (Unsigned integer, 1 byte): Parameter part: Reserved byte in communication setup pdu,保留字節;

2 (Unsigned integer, 2 bytes): Max AmQ (parallel jobs with ack) calling;

3 (Unsigned integer, 2 bytes): Max AmQ (parallel jobs with ack) called;

4 (Unsigned integer, 2 bytes): Parameter part: Negotiate PDU length。協商PDU長度。

舉個例子:

s7comm-setup-communication-job.jpg

圖15 建立通信的請求

那么其確認響應的結構如何呢?跟請求時一樣的,如圖14所示。那么圖16為圖15的確認響應:

s7comm-setup-communication-ack_data.jpg

圖16 建立通信的確認響應

如圖15、16所示,其協商結果為:ACK隊列的大小為1;最大PDU長度為240。

5.2.2?讀取值(Read Var [0x04])

數據讀寫操作通過指定變量的存儲區域(參考6.3 區域(Area names)),地址(偏移量)及其大小或類型(參考6.4.1 Transport sizes in item data)來執行。

先說Job吧!當PDU類型為Job時,那么其S7Comm結構,如圖17所示:

s7comm-read-var-job.png

圖17??S7comm的結構(讀取值的作業請求)

所以,接下來的Parameter字段是item count(項目個數),其類型為Unsigned integer,大小為1 byte。

那么一個item的結構是咋樣的呢?如下(圖17中item1):

0 (Unsigned integer, 1 byte): Variable specification,確定項目結構的主要類型,通常為0x12,代表變量規范;

1 (Unsigned integer, 1 byte): Length of following address specification,本Item其余部分的長度;

2 (Unsigned integer, 1 byte): Syntax Ids of variable specification,確定尋址模式和其余項目結構的格式;

其詳細的Syntax Id,參考6.5?Syntax Ids of variable specification;

3(Unsigned integer, 1 byte): Transport sizes in item data,確定變量的類型和長度:

其詳細的Transport size,參考6.4.1 transport sizes in item data;

4~5 (Unsigned integer ,2 byte): Request?data length,請求的數據長度;

6~7 (Unsigned integer, 2 byte): DB number,DB模塊的編號,如果訪問的不是DB區域,此處為0x0000;

8 (Unsigned integer, 1 byte):: Area,區域類型:

其詳細的區域類型,參考6.3 區域(Area names);

9~11(Unsigned integer, 3 byte): Address,地址。

頭暈了吧?哈哈哈~~先舉個例子:

s7comm-read-var-job.jpg

圖18 讀值操作的作業請求

圖17中item1是讀取DB1的0x000010(DB1.DBX 2.0 BIT 1)值,并且類型為BIT的請求。

PDU類型為Job時,S7Comm結構介紹完了,那PDU類型為Ack_Data時,其S7Comm的結構如何呢?

s7comm-read-var-ack-data.png

圖19??S7comm的結構(讀取值的確認數據響應)

是的,其Parameter只有function、item count兩個字段。

繼續,那么接下來的是Data啦!其結構如下:

0 (Unsigned integer, 1 byte): Return code,返回代碼:

詳細的Return code,請參考6.6.1 Return values of an item response;

1 (Unsigned integer, 1 byte): Transport size,數據的傳輸尺寸:

其詳細的Transport size,參考6.4.2 Transport sizes in data;

2~3 (Unsigned integer, 2 bytes): Length,數據的長度;

4~4+length (?): Data,數據;

? (Unsigned integer, 1 byte): Fill byte,填充字節。

繼續看圖18響應的數據包,如圖20所示:

s7comm-read-var-ack_data.jpg

圖20?讀值操作的確認數據響應

圖20中,item1是讀取DB1的0x000010(DB1.DBX 2.0 BIT 1)值,并且類型為BIT的響應,其響應的數據為01

5.2.3?寫入值(Write Var [0x05])

Write Var中Parameter的結構跟5.2.2?讀取值(Read Var[0x04])一樣,但是Write Va還需寫入值,所以Write Var比Read Var多Data項。結構如下:

s7comm-write-var-job.png

圖21 S7comm的結構(寫入值的作業請求)

由此,Data的結構為:

0 (Unsigned integer, 1 byte): Return code,返回代碼,這里是未定義,所以為Reserved(0x00);

1 (unsigned integer, 1 byte):?Transport size,確定變量的類型和長度:

詳細的Transport size,參考6.4.2 Transport sizes in data;

2-3 (unsigned integer, 2 bytes):?Length,寫入值的數據長度;

4 (1 byte):?Data,寫入的值;

5 (unsigned integer, 1 byte):?Fill byte,填充字節,如果數據的長度不足Length的話,則填充;

舉個例子:

s7comm-write-var-job.jpg

圖22 向地址為0x000008的Flags(M)寫入0x00的作業請求

圖22中,是一個向地址為0x000008的Flags(M)寫入0x00的作業請求。

那PDU類型為Ack_Data時,其S7Comm的結構如何呢?

s7comm-write-var-ack-data.png

圖23?S7comm的結構(寫入值的確認數據響應)

對的,Parameter也只有function、item count兩個字段。而Data中也只有一個Return code字段,其結構如下:

0 (Unsigned integer, 1 byte): Return code,返回代碼:

詳細的Return code,請參考6.6.1 Return values of an item response;

繼續看圖22的響應數據包,如圖24所示:

s7comm-write-var-ack-data.jpg

圖24 向地址為0x000008的Flags(M)寫入0x00的確認響應

圖24中的item1,說明向地址為0x000008的Flags(M)寫入0x00成功!

未完待續。

*本文原創作者:LiukerTeam,本文屬FreeBuf原創獎勵計劃文章,未經許可禁止轉載

本文作者:, 屬于FreeBuf原創獎勵計劃,未經許可禁止轉載

# 工控安全
被以下專輯收錄,發現更多精彩內容
+ 收入我的專輯
評論 按熱度排序

登錄/注冊后在FreeBuf發布內容哦

相關推薦
  • 0 文章數
  • 0 評論數
  • 0 關注者
登錄 / 注冊后在FreeBuf發布內容哦
收入專輯
四月天小说网