165 lines
6.9 KiB
Markdown
165 lines
6.9 KiB
Markdown
+++
|
|
title = "Reverse engineering di un lettore di presenze"
|
|
summary = "Step 1: incominciare a capire come funziona il tutto"
|
|
date = "2024-04-28"
|
|
|
|
tags = ["Reverse Engineering", "Lettore di Presenze", "Decompilazione", "Codemerx"]
|
|
categories = ["Progetti"]
|
|
series = ["Lettore di presenze"]
|
|
series_order = 1
|
|
+++
|
|
|
|
Uno dei motivi per cui ho creato questo blog è per condividere le mie
|
|
esperienze con altri pazzi entusiasti che adorano questo tipo di contenuti di
|
|
nicchia come me.
|
|
|
|
In questa serie di articoli andrò a spiegare come ho eseguito il reverse
|
|
engineering del protocollo di comunicazione usato tra un lettore di presenze ed
|
|
il suo client (ovviamente creato solo per Windows) ed andremo a creare un
|
|
client alternativo con [Rust](https://rust-lang.org/) e
|
|
[Tauri](https://tauri.app/) per rimpiazzare quello proprietario.
|
|
|
|

|
|
|
|
## Un po' di background
|
|
|
|
Mio padre ha voluto aggiornare il vecchio lettore di presenze per la sua
|
|
attività: è volato su Amazon e ha comprato
|
|
l'[R701](https://ipsattendant.it/rilevatore-presenze-r701/) di [I.P.S.
|
|
Informatica](https://ipsinformatica.info/).
|
|
|
|
A differenza del vecchio lettore, con questo i dipendenti possono registrare la
|
|
loro presenza tramite PIN, impronta digitale o tramite un badge RFID, poi le
|
|
registrazioni possono essere scaricate tramite il client ufficiale per Windows
|
|
o tramite una chiavetta USB.
|
|
|
|

|
|
|
|
Il problema è che il client, oltre ad essere installabile solo su Windows e
|
|
richiedere un'account per eseguire azioni offline, non risponde ai requisiti
|
|
dell'azienda.
|
|
|
|
Sarebbe gradito che ogni mese venisse fatto un report per ogni dipendente, con
|
|
una tabella che permetta di vedere le ore lavorate ogni giorno. Invece il
|
|
software ufficiale permette di scaricare solo una lista di presenze, senza
|
|
alcun tipo di divisione per mese o per dipendente, e non permette di esportare
|
|
il tutto in un file `.ods`.
|
|
|
|
Così, in pura modalità "[Stallman quando la nuova stampante Xerox si
|
|
inceppa](https://oreilly.com/openbook/freedom/ch01.html)", ho deciso che la
|
|
soluzione migliore è riscrivere il tutto in modo *open-source*.
|
|
|
|
## Dump delle registrazioni tramite USB
|
|
|
|
Come prima cosa ho provato a scaricare le registrazioni tramite una chiavetta
|
|
USB, dato che questo metodo non necessita di un PC Windows. Così ho formattato
|
|
una chiavetta in FAT32 e, dopo aver creato un utente di test e aver creato
|
|
qualche registrazione, ho scaricato i dati sul mio laptop.
|
|
|
|
Una volta aperto il contenuto della chiavetta ho notato che il lettore ha
|
|
creato due file:
|
|
|
|
* `~tmp.tmp`: che contiene la stringa `usb test!!` ripetuta 384 volte;
|
|
* `AGLog_001.txt`: che contiene le registrazioni.
|
|
|
|
Credo che il file `~tmp.tmp` venga usato dal registratore solo per vedere se la
|
|
chiavetta USB è scrivibile, quindi possoiamo ignorarlo.
|
|
|
|
Aprendo il file `AGLog_001.txt` possiamo andare ad intuire i vari campi che il
|
|
lettore si salva in memoria:
|
|
|
|
```csv
|
|
No Mchn EnNo Name Mode IOMd DateTime
|
|
000001 1 000000001 test 34 0 2024/04/28 16:04:23
|
|
000002 1 000000001 test 33 1 2024/04/28 16:05:28
|
|
000003 1 000000001 test 35 2 2024/04/28 16:08:49
|
|
000004 1 000000001 test 35 3 2024/04/28 16:09:01
|
|
```
|
|
|
|
* `No` è l'ID della registrazione
|
|
* `Mchn` è l'ID del registratore
|
|
* `EnNo` è l'ID del dipendente che ha effettuato la registrazione
|
|
(**En**ployee**No**mber ?)
|
|
* `Name` è il nome del dipendente
|
|
* `Mode` è la modalità con coi il dipendente ha registrato la presenza:
|
|
* `33` è tramite l'impronta digitale
|
|
* `34` è usando il PIN
|
|
* `35` è con il badge
|
|
* `IOMd` è il campo che simboleggia l'ingresso o l'uscita del dipendente
|
|
(**I**n/**O**ut **M**o**d**e ?):
|
|
* `0` è il primo ingresso
|
|
* `1` è la prima uscita
|
|
* `2` è il secondo ingresso
|
|
* `3` è la seconda uscita
|
|
* `Datetime` è la data e l'ora della registrazione
|
|
|
|
Considerando che ho registrato le presenze passando per tutte le modalità di
|
|
ingresso e di uscita in ordine e che ho usato il PIN la prima volta, l'impronta
|
|
digitale la seconda ed il badge le ultime due, possiamo ritenerci soddisfatti
|
|
del risultato.
|
|
|
|
Potremmo addirittura scrivere un programma in Python che usi la libreria
|
|
[csv](https://docs.python.org/3/library/csv.html) per estrarre i dati che ci
|
|
servono da questo file.
|
|
|
|
Ma questo non sarebbe così interessante da essere un post sul mio blog. Non
|
|
voglio entrare nel menù di amministrazione del dispositivo per poi premere in
|
|
ordine i tasti `2`, `1` e `2` per fare il dump, poi prendere il file risultante
|
|
e filtrarlo con uno script Python senza interfaccia grafica.
|
|
|
|
Voglio creare un programma che funzioni nativamente su Windows e Linux e che mi
|
|
permetta di scaricare tutti i dati che mi interessano con un singolo click, già
|
|
formattati correttamente.
|
|
|
|
Prima di tirare fuori [Wireshark](https://wireshark.org/) e provare a sniffare
|
|
dei pacchetti però, voglio provare un'altra tecnica...
|
|
|
|
## Decompilare il client closed-source
|
|
|
|
Come disse una volta [un
|
|
saggio](https://twitter.com/DebugPrivilege/status/1531661046238388226): "Tutto
|
|
il codice è *open-source* se sai leggere Assembly".
|
|
|
|
Dato che la compagnia che ha scritto il codice è italiana e che il client
|
|
funziona solo su Windows, c'è un alta probabilità che il codice sia stato
|
|
scritto in C# su piattaforma .NET.
|
|
|
|
Se questo è il caso, dovrebbe essere abbastanza semplice ottenere il codice
|
|
sorgente tramite un decompilatore come
|
|
[CodemerxDecompile](https://decompiler.codemerx.com/).
|
|
|
|
Quindi ho creato una macchina virtuale con [Windows 10
|
|
AME](https://archive.org/details/windows10-ame-21h1-2021-08-09/) e ho
|
|
installato il client ufficiale alla [versione
|
|
04.03.02](https://ipsattendant.it/download-programmi-e-manuali/).
|
|
|
|
{{< carousel images="images/03-official-client-installation/*"
|
|
aspectRatio="16-9" interval="1000" >}}
|
|
|
|
Una volta installato il client ufficiale ho copiato la directory `C:\Program
|
|
Files (x86)\ipsAttendant` sulla mia macchina Linux e l'ho aperta con
|
|
CodemerxDecompile.
|
|
|
|
Come avevo previsto il codice è scritto in C#, quindi è facilmente leggibile.
|
|
|
|

|
|
|
|
Cercando di qua e di là ho scoperto l'amara verità: dentro al file
|
|
`Dichiarazioni.cs` sono presenti molti metodi interessanti, come
|
|
`FK_ConnectNet()`. Questi metodi però sono tutti import da una libreria
|
|
chiamata `FKAttend.dll`.
|
|
|
|
Cercando sul web, sembra che questa libreria sia in giro da molti anni e dubito
|
|
altamente che l'abbia scritta la compagnia del lettore. Ho trovato anche [la
|
|
documentazione ufficiale del
|
|
DLL](</posts/2024/04/reverse-engineering-an-attendance-clock-part-1/FKAttend User's Manual.pdf>),
|
|
ma nient'altro.
|
|
|
|
Dato che decompilare una libreria che manco il creatore ha avuto voglia di
|
|
implementare da se non è una cosa che sono disposto a fare, nel prossimo
|
|
articolo proveremo a fare il reverse engineering della comunicazione che
|
|
avviene tra client e dispositivo.
|