Parfois, vous n'avez pas d'outil pour consulter les événements applicatifs. D'autre fois, on ne veut même pas vous y donner accès. Par contre, on aura bien voulu vous donner une archive bourrée de fichiers de logs sur un poste dédié. Mais que faire avec cet amas d'octets quand on a qu'un système unix entre les mains ? Regardons ensemble.
Comme sujet de pratique, nous allons explorer les logs d'un honeypot pour trouver des traces d'attaques et voir d'où elles peuvent venir (géographiquement). Un honeypot dans le domaine de la sécurité est une machine destinée à être attaquée pour observer des comportements malveillants. Nous nous baserons sur les logs disponibles sur ce site : http://old.honeynet.org/scans/scan34/. Le plus souvent, dans un environnement où ce type de besoin est fréquent, vous serez équipés d'outils qui feront toutes ces étapes pour vous et agiront même selon les événements de sécurité. Mais il arrive que ces outils ne soient pas présents, ou que vous ayez besoin de sortir des sentier battus proposés par les-dits outils. Plus généralement ces commandes sont des connaissances de base en système unix. Elles vous serviront autant pour de l’administration du système que pour des tâches spécialisées comme l’audit d’une base de code par exemple.
Ce que vous pourrez faire à l'issue de cet article :
Dans cet article certaines commandes nécessitent l'utilisation d'expressions régulières (aussi appelées regex). Je ne décrirai pas la façon de les utiliser. Mais sachez, si vous vous documentez sur le sujet, que les différents langages n'ont pas exactement les mêmes notations.
À la fin de cet article vous trouverez une fiche rapide de référence sur toutes les commandes que nous aurons vues.
Pour toutes les commandes que nous allons voir, je vous encourage à lancer un man
(pour manuel) pour voir à quoi ressemble la doc de la commande en question. Chercher dans cette doc les éléments que je vais vous présenter vous donnera un réflexe qui vous servira pour toujours ! Enfin tant que vous serez dans un shell unix.
Exemple pour consulter la doc de la commande echo
:
$ man echo
NAME
echo -- write arguments to the standard output
SYNOPSIS
echo [-n] [string ...]
DESCRIPTION
[...]
Une fois dans la doc vous pouvez également faire des recherches avec la commande /
. Par exemple si je cherche des informations sur les retours à la ligne, une fois dans la page de manuel de echo
je tape la touche /
suivi du mot clé que je cherche :
/newline
Après avoir téléchargé le fichier SotM34-anton.tar.gz
, nous allons l'ouvrir. Selon l'extension, tar
signifie que c'est une archive de type tar
qui peut être extraite avec le programme du même nom, et gz
signifie que l'archive est compressée (l'extension tgz
est une contraction avec les mêmes significations). Nous l'ouvrons alors avec cette commande :
$ tar xzf SotM34-anton.tar.gz
Dans le détail cette commande est composée de :
tar
: le programme qui permet de créer, et ouvrir des archivesx
: pour extract, dit à tar
d'extraire le contenu (l'option c
, pour compress, permet au contraire de compresser des fichiers)z
: indique que l'archive doit être décompresséef
: permet de spécifier l'archive à ouvrirSotM34-anton.tar.gz
: le nom de l'archive sur laquelle nous travaillonsAprès avoir exécuté cette commande, vous devriez voir apparaitre le dossier SotM34
à côté de l'archive. Celui-ci contient les logs qui nous intéressent.
N'oubliez pas de faire un man tar
pour retrouver les options présentées ici !
Maintenant que nous avons nos logs, commençons par les traces les plus simples et évidentes à trouver : une attaque brute-force sur le login de la machine. Cherchons alors des événements répétés dans les logs secure
de syslog
qui contiennent les événements de login.
Après un cd syslog
, affichons chaque ligne des fichiers secure
:
$ cat secure*
cat
est le programme d'affichagesecure*
signifie que nous allons lister tous les fichiers commençant par secure suivi de n'importe quel texte. Dans notre cas, c'est comme si nous avions lancé cette commande : cat secure secure.1 secure.2 secure.3 secure.4 secure.5 secure.6
Un extrait du résultat:
Mar 13 16:26:09 combo sshd[8714]: Accepted password for test from 59.120.2.133 port 57019 ssh2
Mar 13 16:26:09 combo sshd[8716]: Accepted password for test from 59.120.2.133 port 57023 ssh2
Mar 13 16:26:09 combo sshd[8721]: Accepted password for test from 59.120.2.133 port 57051 ssh2
Mar 13 16:26:09 combo sshd[8720]: Accepted password for test from 59.120.2.133 port 57049 ssh2
[...]
Ce qui s'affiche est tout le contenu des fichiers. On peut voir plusieurs lignes différentes, mais chercher les traces d'attaque dans ce résultat est fastidieux. Voyons comment extraire cette information de ces lignes de texte.
Nous allons faire en sorte que seules les lignes avec des tentatives échouées de login pour mauvais mot de passe s'affichent. On voit dans les lignes affichées avec la commande précédente que certaines lignes ressemblent à ça :
Feb 5 04:32:25 combo sshd[9703]: Failed password for nobody from 210.3.2.8 port 53044 ssh2
La partie commune à toutes les tentatives échouées est donc : Failed password
. Nous allons alors filtrer les lignes pour n'avoir que celles qui contiennent ces deux mots.
$ grep 'Failed password' secure*
grep
est la commande qui permet de filtrer des lignes de texte'Failed password'
est la chaîne que nous voulons sélectionnersecure*
est comme pour cat
la liste des fichiers commençant par secure
Un extrait du résultat:
secure:Mar 13 22:50:55 combo sshd[9356]: Failed password for root from 67.103.15.70 port 55639 ssh2
secure:Mar 13 22:51:07 combo sshd[9358]: Failed password for root from 67.103.15.70 port 55895 ssh2
secure:Mar 13 22:51:18 combo sshd[9360]: Failed password for root from 67.103.15.70 port 56110 ssh2
[...]
Mais comment savoir combien de tentatives échouées le serveur à subit ?
Pour connaître le nombre de lignes, j'ai utilisé une autre commande : wc
(word count). Cet utilitaire permet de compter les mots, lignes, nombre de caractères et bytes.
Pour connaître le nombre de lignes dans le fichier secure.1
:
$ wc -l secure.1
wc
: l'utilitaire qui permet de compter-l
: l'option qui permet de ne compter que le nombre de lignessecure.1
: le fichier dont on veut compter le nombre de lignesLe résultat:
234 secure.1
Sauf que le résultat de grep n'est pas un fichier. Pour la plupart des commandes que je vous présente dans l'article, celles-ci peuvent être exécutées sur des fichiers, mais également sur l'entrée standard. L'entrée standard c'est le nom que l'on donne aux "champs" qui nous permettent de donner des informations à des programmes. Par exemple quand vous tapez une commande, vous la donnez à l'entrée standard.
Essayons en tapant wc -l
seul : le programme sera en attente d'informations. Vous pouvez alors taper tout ce que vous voulez et même revenir à la ligne. Pour sortir de l'entrée standard il faut notifier wc que nous avons terminé avec la combinaison de touches ctrl-D
qui, sous un système unix, envoie le signal EOF pour End Of File. Vous verrez alors un résultat qui ressemble à celui que vous avez obtenu en donnant un fichier à wc
$ wc -l
Un exemple
Avec
Des lignes
3
Cependant, ce que donne grep
en résultat vient sur la sortie standard (et non l'entrée). Pour envoyer la sortie standard d'un programme sur l'entrée standard d'un autre, Unix propose le pipe noté |
.
Si on chaîne les commandes grep
et wc
nous avons alors :
$ grep 'Failed password' secure* | wc -l
702
Le caractère |
sera très souvent utilisé tout le long de cet article car il permet de combiner autant de commandes que l'on veut. Et si vous tentiez d'utiliser la commande grep
à nouveau retrouver les tentatives échouées ? Et cette fois-ci, tentez d'utiliser pipe
, sans donner directement des fichiers à grep
.
Dans le résultat de la commande grep
, nous pouvons voir plusieurs IP différentes. Certaines tentatives échouées pourraient être anecdotiques, mais d'autres bien plus nombreuses ressemblent plutôt à un comportement malveillant.
Nous allons alors extraire les IPs de nos attaquants avec la commande grep
à nouveau, mais cette fois-ci avec une option permettant de ne garder en sortie standard que la condition qu'on lui spécifie :
$ grep 'Failed password' secure* | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
-E
: signifie que nous utilisons une expression régulière et non une chaîne de caractère simple-o
: signifie que seul ce qui correspondra à la regex sera affiché en sortie standard (au lieu de toute la ligne)[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
correspond à une regex pour filtrer des IP très grossièrement, chaque partie porte ce sens :[0-9]
: n'importe quel caractère allant de 0 à 9{1,3}
: entre 1 et 3 caractères\.
: le caractère .
Un extrait du résultat:
67.103.15.70
67.103.15.70
67.103.15.70
67.103.15.70
67.103.15.70
67.103.15.70
67.103.15.70
67.103.15.70
128.59.112.2
[...]
Nous avons alors réussi à extraire les IPs !
Toutes ces IPs c'est bien mais wc
ne permet de compter qu'un nombre total de lignes. Il faut alors compter en distinguant les lignes qui se ressemblent ! On va alors utiliser la commande uniq
qui permet de distinguer les lignes similaires :
$ grep 'Failed password' secure* | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | uniq -c
uniq
: la commande qui permet de distinguer les lignes identiques-c
: qui permet de compter le nombre de lignes identiquesUn extrait du résultat:
[...]
9 202.110.184.100
2 67.103.15.70
17 210.125.27.175
14 202.110.184.100
Le résultat est déjà plus intéressant, mais on remarque que les mêmes IPs apparaissent plusieurs fois. uniq -c
ne distingue que les lignes identiques consécutives, il faudrait trouver un moyen de regrouper toutes les lignes identiques. On va pour cela utiliser la commande sort
juste avant que uniq
prenne la main :
$ grep 'Failed password' secure* | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq -c
sort
: trie les lignes dans l'ordre croissantuniq -c
: commande exécutée précédemment qui permet de regrouper et de compter les lignes identiques consécutivesUn extrait du résultat:
23 128.59.112.2
1 148.228.20.76
8 198.107.38.61
[...]
Et pour aller plus loin nous allons même retrier les lignes pour avoir les IPs les plus présentes vers la fin de la liste :
$ grep 'Failed password' secure* | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq -c | sort
Un extrait du résultat:
1 148.228.20.76
1 82.76.137.124
2 202.69.66.162
2 211.141.89.73
[...]
Notre ligne de commande commence à être assez longue. Nous allons donc stocker nos résultats.
On pourrait stocker le résultat dans un fichier si on voulait s'en resservir plus tard :
$ grep 'Failed password' secure* | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq -c | sort > bad_ips
>
: redirige la sortie standard vers un fichierbad_ips
: le nom du fichier dans lequel nous stockerons les lignesPour se resservir du fichier, il suffit de se resservir de cat
sur le fichier pour reprendre là où on en était.
On pourrait également stocker le résultat dans une variable qui ne durera que le temps que notre terminal sera ouvert :
$ bad_ips=$(grep 'Failed password' secure* | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort | uniq -c | sort)
bad_ips=$( ... )
: stocke dans la variable bad_ips
le résultat de la commande qui se trouve entre les parenthèsesPour se resservir de la variable nous pouvons utiliser
$ echo "${bad_ips}"
${...}
: permet de demander une variable préalablement remplieecho
, hors nous voulons garder la suite de ligne. Si vous tentez un echo
sans les guillemets, vous verrez que tous les paramètres auront été affichés côte à côte.Pour la suite, j'utiliserai la variable, mais n'hésitez pas à utiliser la version fichier, le résultat sera le même !
Dans cette liste d'IPs, toutes ne sont pas nécessairement intéressantes. Ici on va se concentrer sur l'extraction des 5 IPs les plus représentées dans les tentatives échouées. Notre liste étant déjà triée par ordre croissant, il faudrait que nous ne puissions afficher que les 5 dernières lignes. Pour cela, nous allons utiliser la commande tail
:
$ echo "${bad_ips}" | tail -n 5
tail
: la commande qui permet d'afficher les dernières lignes fournies en entrée standard ou par fichier-n 5
: l'option n permet de spécifier le nombre de lignes que l'on veut afficherLe résultat:
32 81.56.82.49
80 222.237.79.237
80 62.193.229.186
80 66.79.166.130
93 202.110.184.100
Nous avons donc les lignes, mais il nous faudrait uniquement les IPs, pas le nombre. Nous allons donc réécrire les lignes pour n'avoir plus que les IPs. awk
est un programme qui permet d'effectuer des actions sur les lignes, un peu comme une fonction map. Lorsqu'il est exécuté :
$ echo "${bad_ips}" | tail -n 5 | awk -F ' ' '{print $2}'
awk
: le programme qui va transformer les lignes-F ' '
: cette option permet de définir un séparateur, et comme sur nos lignes il y a un espace entre le nombre et l'IP, nous spécifions un espace (par défaut awk
gère déjà l'espace, je l'ai placé ici pour l'exemple){print $2}
: l'action à réaliser, ici on demande à afficher la deuxième colonne (de part et d'autre du séparateur), $0
permet d'afficher toute la ligneLe résultat:
81.56.82.49
222.237.79.237
62.193.229.186
66.79.166.130
202.110.184.100
Voilà nos 5 IPs !
Et si nous tentions d'obtenir la localisation de ces 5 IPs ? Un service gratuit https://hackertarget.com/geoip-ip-location-lookup/ permet d'appeler une API (max 100 appels par jour) pour obtenir la localisation d'une IP. Ce type de service est notamment utilisé en détection de fraude, par exemple par des partenaires de paiement pour des sites de billetterie, afin de désactiver l'accès d'une région à un service si le taux de fraude de cette provenance est trop important. L'url proposée s'utilise en ajoutant l'IP à la fin de l'URL, dans les query parameters : https://api.hackertarget.com/geoip/?q=1.1.1.1 . Nous utiliserons donc la commande curl
qui permet de faire des appels http de cette façon : curl https://api.hackertarget.com/geoip/?q=1.1.1.1
Jusque là nous ne faisions que transmettre la sortie standard vers l'entrée standard, mais dans ce cas nous ne pourrons pas simplement laisser la commande se débrouiller avec cette entrée car elle doit faire quelque chose de spécifique : ajouter le paramètre à la fin de l'URL.
Deux méthodes sont dans ce cas possible. La première méthode implique de reformarter les lignes avec awk
, qui est un outil que nous avons déjà vu. Nous allons donc en utiliser une seconde qui consiste à utiliser xargs
pour arranger des paramètres pour une autre commande. Le nombre d'appels au service étant limité, je vous propose de stocker le résultat dans un fichier ou une variable au choix pour s'en resservir sans refaire les appels http.
$ echo "${bad_ips}" | tail -n 5 | awk '{print $2}' | xargs -I{} curl -w "\n" https://api.hackertarget.com/geoip/?q={} > bad_ips_location
xargs
: la commande qui permet d'arranger les paramètres pour une autre commande, ici curl
-I {}
: cette option décrit quel symbole utiliser, ici {}
, pour représenter la ligne en entrée (la notation {}
est semble-t-il standard, parce que ce serait celle de find
, je vous laisse vérifier par vous-même !)curl
: la commande qui fera l'appel http (celle-ci me sert très souvent)-w "\n"
: l'option de curl
qui permet d'ajouter du texte à la fin de la réponse, ici on veut un retour à la ligne après chaque réponsehttps://api.hackertarget.com/geoip/?q={}
: l'URL que nous voulons appeler dans laquelle nous avons placé notre symbole décrit avec -I
> bad_ips_location
: comme vu plus haut, on redirige la sortie standard de curl
vers un fichier pour stocker le résultatUn extrait du résultat après un cat bad_ips_location
:
[...]
IP Address: 62.193.229.186
Country: France
State: Provence-Alpes-Cote d'Azur
City:
Latitude: 43.2854
Longitude: 5.3761
[...]
Et nous avons différentes informations comme le pays et la région d'où proviennent les IPs. Et voilà !
Il faut cependant noter qu’une IP ne donne pas nécessairement la véritable adresse de l’attaquant. D’un part elle pourrait être celle d’un VPN utilisé pour cacher l’origine réelle. D’autre part cette IP pourrait être celle d’un zombie, c’est à dire un appareil piraté dans le but d’émettre des attaques (comme une webcam dont on aurait pas changé le mot de passe par défaut). Dans le cas d’un déni de service, ces appareils zombies peuvent attaquer par milliers pour rendre le ban d’IP inutile.
Et si on visualisait la localisation des IPs sur une carte ? Il faudrait pouvoir appeler une url vers une carte avec la latitude et la longitude en paramètre, sauf que dans notre cas, ces valeurs ne sont pas sur les mêmes lignes. Alors comment les capturer ? Plusieurs méthodes permettent d'y parvenir, mais nous allons principalement réutiliser les mêmes commandes pour explorer d'autres de leurs options.
On va commencer par ne filtrer que les lignes indiquant la Latitude et la Longitude. Ces lignes étant consécutives, on va se servir de l'option de contexte -A
de grep
$ cat bad_ips_location | grep --no-group-separator -A1 Latitude
grep
: la commande qui nous permet de sélectionner les lignes--no-group-separator
: empêche grep
d'afficher un séparateur entre les lignes de contexte (Attention, sous osx ce paramètre n'existe pas et n'est pas nécessaire)-A1
: demande à afficher 1 ligne après la ligne sélectionnée (-B
permet d'afficher les lignes d'avant)Latitude
: le texte à sélectionnerUn extrait du résultat:
[...]
Latitude: 43.2854
Longitude: 5.3761
[...]
Une fois ces lignes affichées, nous allons afficher sur la même ligne la latitude et la longitude. awk
permet d'exécuter des commandes complexes sous forme de script shell. Nous allons stocker la latitude dans une variable quand on tombera sur cette ligne, et afficher le contenu de la variable et la ligne courante quand la ligne courante est la longitude.
$ cat bad_ips_location | grep --no-group-separator -A1 Latitude | awk '{if (/Longitude/) print lat " " $0; lat=$0}'
awk
: notre commande de transformation de ligneawk
peut être vu de cette façon :
{ # début du script
if (/Longitude/) # si la ligne courante contient 'Longitude'
print lat " " $0 # alors on affiche la variable latitude puis un espace et la ligne courante (donc la longitude)
; # fin du alors, début du sinon
lat=$0 # sinon on stocke le contenu de la ligne courante (qui devrait être la latitude)
} # fin du script
Les parties alors et sinon peuvent contenir plusieurs commandes, mais dans ce cas chaque partie doit être encadrée d'accolades, et les instructions à l'intérieur doivent être séparées par des ;
.
Le résultat:
Latitude: 43.5995 Longitude: 1.4332
Latitude: 37.5112 Longitude: 126.9741
Latitude: 43.2854 Longitude: 5.3761
Latitude: 37.3249 Longitude: -121.9153
Latitude: 30.5801 Longitude: 114.2734
On a donc désormais la latitude et la longitude sur une même ligne.
Nous allons finir en utilisant une commande que nous avons déjà vu pour transformer les lignes et extraire les colonnes qui nous intéressent. Vous remarquerez que nous aurions pu utiliser presque exactement cette commande à la place de xargs
pour faire notre première requête qui nous a donné les lieux.
$ cat bad_ips_location | grep --no-group-separator -A1 Latitude | awk '{if (/Longitude/) print lat " " $0; lat=$0}' | awk '{print "https://www.openstreetmap.org/#map=14/" $2 "/" $4}'
awk
: notre commande de transformation de ligne{print "https://www.openstreetmap.org/#map=14/" $2 "/" $4}
: on affiche l'URL openstreetmap, suivie de la deuxième colonne (valeur de la latitude), suivie d'un slash pour respecter le format des paramètre de l'URL, suivi de la quatrième colonne (valeur de la longitude)Un extrait du résultat:
[...]
https://www.openstreetmap.org/#map=14/37.5112/126.9741
[...]
Et voilà des liens qui nous afficherons l'emplacement des IPs sur une carte !
Vous pouvez retrouver l'ensemble des commandes de ce tuto ici :
Code snippet loading ... https://gitlab.com/snippets/1853884.js
La plupart des exemples suivants consomment un fichier. Mais n'oubliez pas qu'il peut consommer la sortie standard d'une autre commande à travers |
.
man some_command
/
: une fois dans man
, cette touche permet de rechercher du texte (e.g.: /ma recherche
)tar xzf file.tar.gz
tar
: le programme qui permet de créer, et ouvrir des archivesx
: dit à tar
d'extraire le contenu (l'option c
permet au contraire de créer une archive, cf man tar
)z
: indique que l'archive doit être décompressée (inutile si l'archive n'est qu'un file.tar
)f
: permet de spécifier l'archive à ouvrirfile.tar.gz
: le nom de l'archive sur laquelle nous travaillonscat secure*
cat
est le programme d'affichagenom*
signifie que nous allons lister tous les fichiers commençant par nom suivi de n'importe quel texte. Dans le cas de cet article, cat secure*
revient à faire : cat secure secure.1 secure.2 secure.3 secure.4 secure.5 secure.6
grep 'chaîne à rechercher' nom*
grep
est la commande qui permet de filtrer des lignes de texte'chaîne à rechercher'
est la chaîne que nous voulons sélectionnernom*
est comme pour cat
la liste des fichiers commençant par nom
grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' filename
grep
est la commande qui permet de filtrer des lignes de texte-E
: signifie que nous utilisons une expression régulière et non une chaîne de caractère simple-o
: signifie que seul ce qui correspondra à la regex sera affiché en sortie standard (au lieu de toute la ligne)[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}
correspond à une regex pour filtrer des IP très grossièrement, chaque partie porte ce sens :[0-9]
: n'importe quel caractère allant de 0 à 9{1,3}
: entre 1 et 3 caractères\.
: le caractère .
grep --no-group-separator -A1 Latitude filename
grep
: la commande qui nous permet de sélectionner les lignes--no-group-separator
: empêche grep
d'afficher un séparateur entre les lignes de contexte (Attention, sous osx ce paramètre n'existe pas et n'est pas nécessaire)-A1
: demande à afficher 1 ligne après la ligne sélectionnée (-B
permet d'afficher les lignes d'avant)Latitude
: le texte à sélectionnerwc -l filename
wc
: l'utilitaire qui permet de compter-l
: l'option qui permet de ne compter que le nombre de lignesfilename
: le fichier dont on veut compter le nombre de lignessort filename
sort
: trie les lignes dans l'ordre croissantuniq -c filename
uniq
: la commande qui permet de distinguer les lignes identiques consécutives, faire un sort
au préalable si on veut éliminer les doublons non consécutifs mais attention vous perdrez l'ordre d'apparition des lignes à l'origine-c
: qui permet de compter le nombre de lignes identiquessome_command > filename
>
: redirige la sortie standard vers un fichierfilename
: le nom du fichier dans lequel nous stockerons les lignescat filename
bad_ips=$(some_command)
filename=$( ... )
: stocke dans la variable filename
le résultat de la commande qui se trouve entre les parenthèsesecho "${filename}"
tail -n 5 filename
tail
: la commande qui permet d'afficher les dernières lignes fournies en entrée standard ou par fichier-n 5
: l'option n permet de spécifier le nombre de lignes que l'on veut afficher-f
permet d'afficher les dernières lignes d'un fichier pendant qu'il est en cours d'écriture (utile par exemple quand ils s'agit de logs)head
some_command | xargs -I{} somecommand {}
xargs
: la commande qui permet d'arranger les paramètres pour une autre commande, ici curl
-I {}
: cette option décrit quel symbole utiliser, ici {}
, pour représenter la ligne en entréecurl
: la commande qui fera l'appel http-w "\n"
: l'option de curl
qui permet d'ajouter du texte à la fin de la réponsehttps://api.hackertarget.com/geoip/?q={}
: l'URL que nous voulons appeler dans laquelle nous avons placé notre symbole décrit avec -I
awk -F ' ' '{print $2}'
awk
: le programme qui va transformer les lignes, un peu comme une fonction map-F ' '
: cette option permet de définir un séparateur, et comme sur nos lignes il y a un espace entre le nombre et l'IP, nous spécifions un espace (par défaut awk
gère déjà l'espace, je l'ai placé ici pour l'exemple){print $2}
: l'action à réaliser, ici on demande à afficher la deuxième colonne (de part et d'autre du séparateur), $0
permet d'afficher toute la ligneawk '{if (/Longitude/) print lat " " $0; lat=$0}' filename
awk
: notre commande de transformation de ligneawk
peut être vu de cette façon :
{ # début du script
if (/Longitude/) # si la ligne courante contient 'Longitude'
print lat " " $0 # alors on affiche la variable latitude puis un espace et la ligne courante (donc la longitude)
; # fin du alors, début du sinon
lat=$0 # sinon on stocke le contenu de la ligne courante (qui devrait être la latitude)
} # fin du script