Tags: master registers rtu modbus slave
Rating:
### Industrial Network
*[Don't follow my github repo for CTF](https://github.com/spitfirerxf)*
_In an industrial Modbus RTU network based on RS485 bus, the master wants to read a sensor data, the data packet has been sent to the slave is like below. Send the slave response to the master, also imagine the slave data is 40 (decimal). (data is in Hex format) Master req. = 06 03 00 00 00 01 85 BD The answer is not in the regular flag format._
So let's parse the master's request according to [this Modbus documentation](https://www.modbustools.com/modbus.html):
```
06 03 00 00 00 01 85 BD
06 is the slave number
03 is the function, and here it's Read Holding Register
00 00 is the register number offset, 00 00 is counting from register 0
00 01 is the number of register read, incrementally from the offset
85 BD is the two CRC
```
So basically it's just asking for register value in slave number 06. Now we can expect the slave's answer:
```
06 03 02 00 28 0D 9A
06 is slave number
03 function
02 is the byte, per register holding 2 bytes
00 28 is the actual data, 40 in decimal
0D 9A is two CRC
```
Then how's the CRC calculated? We found a [simple C script](https://ctlsys.com/support/how_to_compute_the_modbus_rtu_message_crc/) to calculate it for us, and modified it a bit:
```
#include <stdio.h>
#define BYTE unsigned char
#define WORD unsigned short
#define HIGH(x) ((x & 0xff00) >> 8)
#define LOW(x) (x & 0x00ff)
unsigned short ModRTU_CC(unsigned char *buf, int len)
{
unsigned short crc = 0xFFFF;
for(int pos = 0; pos < len; pos++){
crc ^= (unsigned short)buf[pos];
for (int i = 9; i != 0; i--){
if((crc & 0x0001) != 0){
crc >>= 1;
crc ^= 0xA001;
}
else crc >>= 1;
}
}
}
int main() {
unsigned char buf[] = {
0x6,0x3,0x2,0x0,0x28
};
unsigned short crc = ModRTU_CRC(buf, sizeof(buf));
printf("crc: %02X %02X\n", LOW(crc), HIGH(crc));
return 0;
}
```
```
crc: 0D 9A
```
Flag: `06 03 02 00 28 0D 9A`