
Riconoscimento di pattern per host, servizi e contenuti.
# Recog: un framework di riconoscimento
[](https://github.com/rapid7/recog/actions/workflows/ci.yml)
[](https://github.com/rapid7/recog/actions/workflows/verify.yml)
Recog è un framework per l'identificazione di prodotti, servizi, sistemi operativi e hardware confrontando le impronte digitali con i dati restituiti da vari probe di rete. Recog semplifica l'estrazione di informazioni utili dai banner dei server web, dai campi di descrizione del sistema SNMP e molto altro.
Recog è open source; consultare il file [LICENSE](https://github.com/rapid7/recog/blob/main/LICENSE) per maggiori informazioni.
## Indice
1. [Separazione del repository](#repository-split)
1. [Rinomina del branch predefinito](#default-branch-rename)
1. [Implementazioni della libreria Recog per linguaggio](#recog-library-language-implementations)
1. [Parità delle funzionalità](#feature-parity)
1. [Installazione](#installation)
1. [Maturità](#maturity)
1. [Impronte digitali](#fingerprints)
1. [Testare le corrispondenze](#testing-matches)
1. [ftp_banners](#ftp_banners)
1. [http_cookies](#http_cookies)
1. [http_servers](#http_servers)
1. [favicons](#favicons)
1. [http_wwwauth](#http_wwwauth)
1. [tls_jarm](#tls_jarm)
1. [Contribuire](#contributing)
## Separazione del repository
Il 31 marzo 2022, il contenuto di Recog - i file XML delle impronte digitali e le utility - è stato separato dall'implementazione della libreria del framework Recog. Il repository originale [Recog](https://github.com/rapid7/recog) ora contiene il contenuto di Recog e il repository [Recog-Ruby](https://github.com/rapid7/recog-ruby) contiene l'implementazione in linguaggio Ruby. Il contenuto di Recog è incluso in Recog-Ruby come sottomodulo git ed è annidato nella directory `recog`. Tutte le versioni della gemma Recog successive alla separazione, uguali o superiori alla 3.0.0: 1. conterranno la directory delle impronte XML nella directory `recog` e 2. includeranno solo lo strumento `recog_match` poiché gli altri strumenti sono focalizzati sulla gestione delle impronte digitali.
[^torna su](#recog-a-recognition-framework)
### Rinomina del branch predefinito
Insieme alla separazione del repository, il branch predefinito è stato rinominato da `master` a `main`. Eventuali cloni creati prima di queste modifiche dovranno essere aggiornati manualmente nel proprio ambiente locale. Se disponi di un fork, vai alle impostazioni del fork e segui le istruzioni su [rinominare un branch](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-branches-in-your-repository/renaming-a-branch) per impostare il branch predefinito su `main`.
```
git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a
```
Facoltativamente, eseguire il seguente comando per rimuovere i riferimenti di tracciamento al vecchio nome del branch.
```
# dry-run to confirm stale references that will be deleted before proceeding
git remote prune origin --dry-run
git remote prune origin
```
Se in precedenza hai utilizzato il branch di tracciamento upstream `upstream-master`, esegui i seguenti comandi per rimuovere il vecchio branch e crearne uno nuovo di tracciamento upstream.
```
git branch -d upstream-master
git checkout -b upstream-main --track upstream/main
```
Facoltativamente, eseguire il seguente comando per rimuovere i riferimenti di tracciamento al vecchio nome del branch upstream.
```
# dry-run to confirm stale references that will be deleted before proceeding
git remote prune upstream --dry-run
git remote prune upstream
```
[^torna su](#recog-a-recognition-framework)
## Implementazioni della libreria Recog per linguaggio
* Ruby: [rapid7/recog-ruby](https://github.com/rapid7/recog-ruby)
* Java: [rapid7/recog-java](https://github.com/rapid7/recog-java)
* Go: [runZeroInc/recog-go](https://github.com/runZeroInc/recog-go)
[^torna su](#recog-a-recognition-framework)
### Parità delle funzionalità
| Funzionalità :sparkles: | rapid7/recog-ruby | rapid7/recog-java | runZeroInc/recog-go |
|---------------------------------------------|:------------------:|:------------------:|:-------------------:|
| Strumento CLI per la verifica delle impronte digitali | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Strumento CLI per la corrispondenza delle impronte digitali | :white_check_mark: | | :white_check_mark: |
| Supporta esempi codificati in base64 | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Supporta esempi esterni basati su filesystem | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Interpolazione dei parametri CPE nella corrispondenza delle impronte | :white_check_mark: | :white_check_mark: | :white_check_mark: |
[^torna su](#recog-a-recognition-framework)
## Installazione
Recog è composto sia da file XML di impronte digitali sia da una serie di codice, per lo più in Ruby, che rende facile sviluppare, testare e utilizzare le impronte digitali in esso contenute. Per utilizzare il codice Ruby incluso, sono necessarie una versione recente di Ruby (2.31+), insieme a Rubygems e alla gemma `bundler`. Una volta installate queste dipendenze, utilizzare i seguenti comandi per recuperare l'ultimo codice sorgente e installare eventuali dipendenze aggiuntive.
```shell
$ git clone [email protected]:rapid7/recog.git
$ cd recog
$ bundle install
```
[^torna su](#recog-a-recognition-framework)
## Maturità
Si noti che, sebbene le impronte digitali XML siano piuttosto stabili e ben testate, il codebase Ruby è ancora abbastanza recente e soggetto a rapidi cambiamenti. Contattateci (research[at]rapid7.com) prima di utilizzare il codice di Recog in progetti di produzione.
[^torna su](#recog-a-recognition-framework)
## Impronte digitali
Le impronte digitali all'interno di Recog sono memorizzate in file XML, ciascuno progettato per corrispondere a una specifica stringa o campo di risposta del protocollo. Ad esempio, il file [ssh_banners.xml](https://github.com/rapid7/recog/blob/main/xml/ssh_banners.xml) può determinare il sistema operativo, il vendor e talvolta il prodotto hardware confrontando la stringa del banner iniziale del demone SSH.
Un file di impronte digitali è costituito da un documento XML come il seguente:
```xml
<fingerprints matches="ssh.banner">
<fingerprint pattern="^RomSShell_([\d\.]+)$">
<description>Allegro RomSShell SSH</description>
<example service.version="4.62">RomSShell_4.62</example>
<param pos="0" name="service.vendor" value="Allegro"/>
<param pos="0" name="service.product" value="RomSShell"/>
<param pos="1" name="service.version"/>
</fingerprint>
</fingerprints>
```
La prima riga deve essere sempre costituita dalla dichiarazione di versione XML. Il primo elemento deve essere sempre un blocco `fingerprints` con un attributo `matches` che indica quali dati questo file di impronte digitali deve confrontare. L'attributo `matches` è normalmente nella forma `protocol.field`.
All'interno dell'elemento `fingerprints` devono esserci uno o più elementi `fingerprint`. Ogni `fingerprint` deve contenere un attributo `pattern`, che contiene l'espressione regolare da utilizzare per il confronto con i dati. È possibile specificare un attributo opzionale `flags` per controllare come l'espressione regolare deve essere interpretata. Consultare [la documentazione di Recog per `FLAG_MAP`](http://www.rubydoc.info/gems/recog/Recog/Fingerprint/RegexpFactory#FLAG_MAP-constant) per maggiori informazioni.
All'interno del fingerprint, un elemento `description` deve contenere una stringa leggibile che descrive questa impronta digitale.
Dovrebbe essere presente almeno un elemento `example`, anche se sono preferiti più elementi `example`. Questi elementi vengono utilizzati come parte della copertura dei test in `rspec`, che verifica che i dati forniti corrispondano all'espressione regolare specificata. Inoltre, se il fingerprint utilizza gli elementi `param` per estrarre i valori dei campi dai dati (descritto di seguito), è possibile aggiungere queste estrazioni previste come attributi degli elementi `example`. Nell'esempio precedente, questo:
```xml
<example service.version="4.62">RomSShell_4.62</example>
```
verifica che `RomSShell_4.62` corrisponda all'espressione regolare fornita e che il valore di `service.version` sia 4.62.
La stringa `example` può essere codificata in base64 per consentire l'uso di caratteri non stampabili. Per segnalarlo a Recog, all'elemento `example` viene aggiunto un attributo `_encoding` con valore `base64`. Il testo codificato in base64 più lungo di 80 caratteri può essere suddiviso su più righe come mostrato di seguito per facilitarne la lettura.
```xml
<example _encoding="base64">
dGllczGEAAAAlQQWMS4yLjg0MC4xMTM1NTYuMS40LjgwMAQuZGF0YS5yZW1vdmVkLjCEAAAAK
AQdZG9tYWluQ29udHJvbGxlckZ1bmN0aW9uYWxpdHkxhAAAAAMEATc=
</example>
```
Inoltre, gli esempi possono essere inseriti in una directory con lo stesso nome base del file XML, nella stessa directory del file XML:
```
xml/services.xml
xml/services/file1
xml/services/file2
...
```
Possono quindi essere caricati utilizzando l'attributo `_filename`:
```xml
<example _filename="file1"/>
```
Ciò è utile per esempi lunghi.
Gli elementi `param` contengono un attributo `pos`, che indica quale campo di acquisizione del `pattern` deve essere estratto, oppure `0` per una stringa statica. L'attributo `name` è la chiave che verrà riportata in caso di corrispondenza riuscita, mentre `value` sarà una stringa statica per valori `pos` pari a `0` oppure assente e ricavato dal campo acquisito.
L'attributo `value` supporta l'interpolazione di dati provenienti da altri campi. Ciò è spesso utile quando si acquisisce il valore per `hw.product` tramite regex e lo si riutilizza in `os.product`.
Ecco un esempio tratto da`http_servers.xml` in cui `hw.product` viene acquisito e riutilizzato.
```xml
<fingerprint pattern="^Eltex (TAU-\d+[A-Z]*(?:\.IP)?)$">
<description>Eltex TAU model VoIP gateway</description>
<example hw.product="TAU-72">Eltex TAU-72</example>
<example hw.product="TAU-1.IP">Eltex TAU-1.IP</example>
<param pos="0" name="os.vendor" value="Eltex"/>
<param pos="0" name="os.product" value="{hw.product} Firmware"/>
<param pos="0" name="os.device" value="VoIP Gateway"/>
<param pos="0" name="hw.vendor" value="Eltex"/>
<param pos="1" name="hw.product"/>
<param pos="0" name="hw.device" value="VoIP Gateway"/>
</fingerprint>
```
C'è una gestione speciale per gli attributi temporanei che hanno un nome che inizia con `_tmp.`. Questi attributi possono essere utilizzati per l'interpolazione ma non vengono emessi nell'output. Ciò è utile quando un determinato nome di prodotto è incoerente tra vari banner, marketing del vendor o valori NIST quando si tenta di generare CPE. In questi casi, le parti utili del banner possono essere estratte e si può creare un nuovo valore senza appesantire i dati emessi da una corrispondenza.
```xml
<fingerprint pattern="^foo baz switchThing-(\d{4})$">
<description>NetCorp NX series switches</description>
<example hw.product="NX8200">foo baz switchThing-8200</example>
<param pos="0" name="hw.vendor" value="NetCorp"/>
<param pos="0" name="hw.product" value="NX{_tmp.001}"/>
<param pos="2" name="_tmp.001"/>
</fingerprint>
```
Questi attributi temporanei non vengono tracciati in `identifiers/fields.txt`.
[^torna su](#recog-a-recognition-framework)
### Testare le corrispondenze
Gli esempi seguenti utilizzano `bin/recog_match`, un semplice strumento da riga di comando in Ruby che usa i dati delle impronte digitali di Recog. Generalmente è richiesta una pre-elaborazione prima di eseguire Recog, ad esempio l'estrazione dei valori degli header HTTP, ecc. Tutti i dati delle impronte digitali si trovano in `xml/*.xml`.
#### ftp_banners
Riconoscere i server FTP in base alla risposta del banner del server dopo la connessione:
```
# Example plaintext input
echo -n '220 Microsoft FTP Service' | bin/recog_match xml/ftp_banners.xml -
# Example command using nmap
nmap -sV -script=banner -p 21 192.168.123.13 | grep --color=never '_banner' | cut -d: -f2- | bin/recog_match xml/ftp_banners.xml -
# Example output
MATCH: {"matched"=>"Microsoft FTP Server on Windows XP, 2003 or later without version", "service.vendor"=>"Microsoft", "service.product"=>"IIS", "service.family"=>"IIS", "service.cpe23"=>"cpe:/a:microsoft:iis:-", "os.vendor"=>"Microsoft", "os.family"=>"Windows", "os.product"=>"Windows", "os.cpe23"=>"cpe:/o:microsoft:windows:-", "host.name"=>"220", "service.protocol"=>"ftp", "fingerprint_db"=>"ftp.banner", "data"=>"220 Microsoft FTP Service"}
```
#### http_cookies
Utilizzo del valore dell'header HTTP `Set-Cookie` per riconoscere un server HTTP:
```
# Example plaintext input
echo 'laravel_session=eyJ...etc..etc...%3D; expires=Mon, 13-Mar-2023 16:48:58 GMT; Max-Age=7200; path=/; httponly; samesite=lax' | bin/recog_match xml/http_cookies.xml -
# Example cURL command
curl --silent -I http://localhost:9001 | grep --color=never -i '^Set-Cookie:' | cut -d: -f2- | bin/recog_match xml/http_cookies.xml -
# Example output
MATCH: {"matched"=>"Laravel PHP web application framework", "service.vendor"=>"Laravel", "service.product"=>"Laravel", "service.cpe23"=>"cpe:/a:laravel:laravel:-", "service.protocol"=>"http", "fingerprint_db"=>"http_header.cookie", "data"=>"laravel_session=eyJ...etc..etc...%3D; expires=Mon, 13-Mar-2023 16:48:58 GMT; Max-Age=7200; path=/; httponly; samesite=lax"}
```
#### http_servers
Utilizzo del valore dell'header HTTP `Server` per riconoscere un server HTTP:
```
# Example plaintext input
echo -n 'Apache/2.4.38 (Debian)' | bin/recog_match xml/http_servers.xml -
# Example cURL command
curl --silent -I http://localhost:9001 | grep --color=never -i '^Server:' | cut -d: -f2- | bin/recog_match xml/http_servers.xml -
# Example output
MATCH: {"matched"=>"Apache", "service.vendor"=>"Apache", "service.product"=>"HTTPD", "service.family"=>"Apache", "service.version"=>"2.4.38", "service.cpe23"=>"cpe:/a:apache:http_server:2.4.38", "apache.info"=>"(Debian)", "service.protocol"=>"http", "fingerprint_db"=>"http_header.server", "data"=>"Apache/2.4.38 (Debian)"}
```
#### favicons
Utilizzo del valore md5sum di una favicon per identificare un servizio in esecuzione:
```
# Example plaintext input
echo -n fe22dd2bb09daccf58256611ac491469 | bin/recog_match xml/favicons.xml -
# Example cURL command
curl --silent http://localhost:8000/favicon.ico | md5sum | awk '{ print $1 }' | bin/recog_match xml/favicons.xml -
# Example output
MATCH: {"matched"=>"Drupal CMS", "service.vendor"=>"Drupal", "service.product"=>"CMS", "service.certainty"=>"0.5", "service.cpe23"=>"cpe:/a:drupal:drupal:-", "service.protocol"=>"", "fingerprint_db"=>"favicon.md5", "data"=>"fe22dd2bb09daccf58256611ac491469"}
```
#### http_wwwauth
Utilizzo del valore dell'header HTTP `WWW-Authenticate` per riconoscere un server HTTP:
```
# Example plaintext input
echo -n 'Basic realm="monit"' | bin/recog_match xml/http_wwwauth.xml -
# Example cURL command
curl --silent -I http://localhost:9001 | grep --color=never -i '^WWW-Authenticate:' | cut -d: -f2- | bin/recog_match xml/http_wwwauth.xml -
# Example output
MATCH: {"matched"=>"Minot", "service.vendor"=>"Tildeslash", "service.product"=>"Monit", "service.cpe23"=>"cpe:/a:tildeslash:monit:-", "service.protocol"=>"http", "fingerprint_db"=>"http_header.wwwauth", "data"=>"Basic realm=\"monit\""}
```
#### tls_jarm
Riconoscere i server TLS in base alla risposta del server a 10 pacchetti TLS Client Hello. Impronta digitale basata su https://github.com/salesforce/jarm
```
# Example plaintext input
echo -n 07d14d16d21d21d07c42d43d000000f50d155305214cf247147c43c0f1a823 | bin/recog_match xml/jarm.xml -
# Example command using Salesforce's JARM against a running Metasploit listener
python3 $code/jarm/jarm.py -p 8443 192.168.123.1 | grep --color=never 'JARM: ' | awk -F: '{ print $2 }' | bin/recog_match xml/tls_jarm.xml -
# Example output
MATCH: {"matched"=>"Metasploit listener", "service.vendor"=>"Rapid7", "service.product"=>"Metasploit", "service.cpe23"=>"cpe:/a:rapid7:metasploit:-", "service.protocol"=>"tls", "fingerprint_db"=>"tls.jarm", "data"=>"07d14d16d21d21d07c42d43d000000f50d155305214cf247147c43c0f1a823"}
```
## Contribuire
Gli utenti e i manutentori di Recog apprezzerebbero molto qualsiasi contributo tu possa apportare al progetto. Per linee guida e istruzioni, consultare [CONTRIBUTING.MD](https://github.com/rapid7/recog/blob/main/CONTRIBUTING.md).
[^torna su](#recog-a-recognition-framework)