Tmphack
Hacking the Amano timecard system device. Inspecting AGX-100 and AGX-10 devices.
Firmware analysis
The device seems to communicate on port 1441.
The bytes captured are:
host <<=>> minidevice Run 1 ====================== >> port 1441 Syn? << Syn! >> 04 "0900" 05 # 04 = new request ? The response seems to be, 01 stuff, 02 stuff, 03 stuff, 04 end << 01 "0001" 02 "09000021800000000080000000 " 03 09 # This says "8" and there are 8 records # possibly read as 09 00002 18 00" as the 18 might be the 17 digits after >> 10 30 # something << 04 # 04 = ok? >> 04 "0700" 05 # new request ? << "0700" 04 # empty? >> 04 "0600" 05 # ? << 01 "0001" 02 "longstringofdata" 03 0d # lots of data >> 10 30 # something? (clear?) << 04 # ok >> 04 "1901" 05 # request for 1901? << 10 30 >> 01 "0002" 02 "1911 " 03 0b # spaces, normal 01,02,03 reply, but what is it << 10 31 # 10 31 now >> 04 # ok >> 04 "0600" 05 # again, give me 0600 again? << "0600" 04 # now its empty >> Fin << Fin
The longstring of data, appears to contain:
01 30 3030 31 "0001" 02 #Start of record, total of 8 records this time 3331 "31" 3230 3038 3130 3033 3038 3436 "200810030846" # known 3030 3031 "0001" 3030 3030 3030 3132 3232 "0000001222" # known 3030 3031 "0001" #Start of next record 3331 "31" ... etc .. 3030 3031 "0001" # end 03 0d
Later on, around noon:
01 "0001" 02 "31" "200810031243" "0003" "0000001148" "8901" "31" # etc # Follow by 8 other "0003" and "8901". We have one: "31" "200810031323" "0004" "0000001139" "0001"
Afternoon:
"31" "200810031602" "0002" "0000001469" "0001"
host <<=>> minidevice Run 2 ====================== >> 04 "0900" 05 << 01 "0001" 02 "09000021800000000240000000 " 03 07 # This says 24 and there are 24 records >> 10 30 << 04 >> 04 "0700" 05 << "0700" 04 >> 04 "0600" 05 << 01 "0001" << 02 "longstringdata" 03 0e # 8 records >> 10 30 << 01 "0001" << 02 "more long data" 03 0e # 8 records >> 10 30 << 01 "0001" << 02 "more long data" 03 04 # 8 records >> 10 30 << 04 >> 04 "1901" 05 << 10 30 >> 01 "0002" 02 "1911 " 03 0b << 10 31 >> 04 >> 04 "0600" 05 << "0600" 04 >> Fin << Fin
AGX-10
Picked up an older device for 1 yen on the auction. Seems to be of a similar design, except the main card reader has only serial, then they have bolted on a serial-to-ethernet adaptor device. When you connect to port 80 it displays the settings that it is redirecting serial 9600 to port 1441.
Testing from my code:
< sent to device : hex of received bytes > string of received bytes
<04"0900"05 :01 30 30 30 31 02 30 39 30 30 30 30 32 30 35 30 :30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 :30 30 31 36 20 20 20 20 20 20 20 20 20 20 03 >'0001090000205000000000000000000016 ' :05 > >10 30 :04 > >04 "0700" 05 :01 30 30 30 31 02 30 37 30 30 32 34 32 30 30 30 :30 30 30 30 30 30 30 30 30 30 30 20 20 20 17 >'0001070024200000000000000 ' :05 > :05 > :04 > >04 "0600" 05 :30 36 30 30 04 >'0600'
This makes me think:
04 OK 05 EOR EndOfRequest? 01 Part1.. 02 Part2.. 03 Part3 CRC 10-30 Status code "0"? Or possibly, "send more". 10-31 Status code "1"? Done, or "completed, dont send more" 15 Error, bad crc, or just bad request
Requests (04-request-05)
// 0000 = empty // 0100 = 0001 01 2008 12 30 1351 19 Time? // 0200 = '000102050100000000020001 030002 040002 0502560008060000 0700030003080000 090001 100000000011000000001200000000 ' // 0300 = empty // 0400 = empty // 0500 = empty // 0600 = get time-entries // 0700 = get time, empty // 0800 = empty // 0900 = get serial and number of entries // 1000 = empty // 1100 = empty // 1200 = empty // ... // 2100 = empty 0900 status and number of entries? 0700 empty for agx-100, and '.0001.0700 210 2008 12 30 1236 10 ' for agx-10. Looks like date/time 0600 send the entries, 8 at a time 1901 clear the entries? // 0101 = ERROR // ... // 0801 = ERROR // 0901 = ERROR // 1001 = 04 // 1101 = 04 // 1201 = 04 // 1301 = 04 // 1401 = ERROR // 1501 = ERROR // 1601 = 04 // 1701 = ERROR // 1801 = ERROR // 1901 = 04 // used for clearing num records // 3101 = ERROR
It is entirely possible that "0900" and "1901" are read, and write, operations for the same information. 0900 reads the number of records, and 1901 writes 01 records back, in this case, blanks to clear it? You could guess then that 0600 reads entries, and 1601 writes one?
It also just occurred to me that my real card has a magnetic strip, and does indeed work with the old unit. This is a record from it:
0001 31 2008 12 30 1815 0001 0000001222 0001
Checksum
01-02-03 seem to be always followed by a checksum byte (&0x0f) so, we need to figure this out:
01 0001 02 09 0 0 0 0 218 00000000 0 8 0000000______________ 03 09 01 0001 02 31 200810030846000100000012220001 01 0001 02 31 200810030925000100000010610001 03 0d 01 0002 02 19 11 ____________ 03 0b 01 0001 02 09 0 0 0 0 218 00000000 2 4 0000000______________ 03 07 01 0001 02 31 200810030933000100000011070001 31 200810030934000100000014550001 31 200810030936000100000011670001 31 200810030941000100000014460001 03 0e 01 0002 02 19 11 ____________ 03 0b 01 0001 02 09 0 0 0 0 218 00000000 0 7 0000000______________ 03 06 01 0001 02 31 200810030958000100000011660001 31 200810031010000100000011620001 ________________________________ 03 06 01 0002 02 19 11 ____________ 03 0b 01 0001 02 09 0 0 0 0 218 00000000 0 2 0000000______________ 03 03 01 0001 02 31 200810031031000100000015510001 31 200810031054000100000011390001 ________________________________ ________________________________ ________________________________ ________________________________ ________________________________ ________________________________ 03 0a 01 0001 02 09 0 0 0 0 218 00000000 0 0 000000000____________ 03 01
Note that the data-get (reply to 0600) always has 8 records in it, or padded out with spaces until final 03.
The two closest packets we have are the two listing 8 entries and 7 entries.
01 0001 02 09 0 0 0 0 218 00000000 0 8 0000000______________ 03 09 01 0001 02 09 0 0 0 0 218 00000000 0 7 0000000______________ 03 06 30 38 30 37 38 => 0011 1000 09 => 1001 37 => 0011 0111 06 => 0110
So it would seem that the CRC is XOR based. It is computed from the first byte following 0x02 (6th byte into the message) and includes the 0x03 byte at the end.