web-dev-qa-db-fra.com

Trouver des fichiers lisibles par l'homme

J'essaie de trouver un moyen efficace de faire le niveau 5 du défi bandit OverTheWire .

Quoi qu'il en soit, j'ai un tas de fichiers, et il n'y en a qu'un qui respecte les critères suivants:

  • Lisible par l'homme
  • Taille de 1033 octets
  • Non exécutable

En ce moment, j'utilise la commande find, et je peux trouver les fichiers correspondant aux 2 derniers critères:

find . -size 1033c ! -executable

Cependant, je ne sais pas comment exclure les fichiers non lisibles par l'homme. Les solutions que j'ai trouvées pour ce défi utilisent le -readable paramètre de test, mais je ne pense pas que cela fonctionne. -readable ne regarde que les autorisations des fichiers, et non leur contenu, tandis que la description du défi demande un fichier ASCII ou quelque chose comme ça.

15
J.Doe

Oui, vous pouvez utiliser find pour rechercher des fichiers non exécutables de la bonne taille, puis utiliser file pour rechercher ASCII. Quelque chose comme:

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

La question, cependant, n'est pas aussi simple qu'il y paraît. "Lisible par l'homme" est un terme horriblement vague. Vraisemblablement, vous voulez dire du texte. OK, mais quel genre de texte? Caractère latin ASCII uniquement? Unicode complet? Par exemple, considérez ces trois fichiers:

$ cat file1
abcde
$ cat file2
αβγδε
$ cat file3
abcde
αβγδε
$ cat file4
#!/bin/sh
echo foo

Ce sont tous des textes et lisibles par l'homme. Voyons maintenant ce que file en fait:

$ file *
file1: ASCII text
file2: UTF-8 Unicode text
file3: UTF-8 Unicode text
file4: POSIX Shell script, ASCII text executable

Ainsi, la commande find ci-dessus ne trouvera que file1 (pour cet exemple, imaginons que ces fichiers contiennent 1033 caractères). Vous pouvez développer le find pour rechercher la chaîne text:

find . -type f -size 1033c ! -executable -exec file {} + | grep -w text

Avec le -w, grep imprimera uniquement les lignes où text se trouve en tant que mot autonome. Cela devrait être assez proche de ce que vous voulez, mais je ne peux pas garantir qu'il n'y a pas d'autre type de fichier dont la description pourrait également inclure la chaîne text.

17
terdon

Tandis que -exec est principalement utilisé pour faire quelque chose avec les fichiers qui, lorsqu'ils ont été trouvés, peuvent également servir de test. Par conséquent, nous pouvons l'ajouter à vos autres critères:

find . \
  -size 1033c \
  -not -executable \
  -exec sh -c 'file {} | grep "text$"' \;

N'oubliez pas que grep renvoie une valeur non nulle lorsque le modèle n'a pas été trouvé et sh -c "COMMAND" renverra le résultat de l'évaluation (tant qu'il est valide). Donc, cela n'imprimera que les fichiers où file <filename> crache quelque chose qui se termine par text, par exemple "Texte Unicode UTF-8" ou "Texte ASCII", mais pas "Texte ASCII étendu non ISO, avec séquences d'échappement".

En une seule ligne, cela finit même plus court que de parcourir xargs:

find . -size 1033c -not -executable -exec sh -c 'file {} | grep "text$"' \;

N'oubliez pas que vous pouvez remplacer sh -c 'file {} | grep "text$"' avec n'importe quelle commande personnalisée. Si vous souhaitez rechercher quelque chose de très complexe, il peut être préférable de fournir un script Shell et de l'utiliser à la place:

find . -size 1033c -not -executable -exec is_human_readable.sh {} \;

qui, à long terme, est plus facile à entretenir que l'historique de votre Shell:

#!/bin/sh
file "$@" | grep "text$" > /dev/null
4
Zeta
find . -size 1033c ! -executable -exec file {} +
2
user305801

Il vous suffit d'utiliser:

find inhere -size 1033c

Il vous donnera le seul fichier contenant le mot de passe.

1
BugHunterUK

Exécutez simplement ce qui suit contre le contenu du répertoire:

$ file -- *
-file00: data
-file01: data
-file02: data
-file03: data
-file04: data
-file05: data
-file06: data
-file07: ASCII text
-file08: data
-file09: data
$ cat -- \-file07
<output>
1
t0lkim
bandit4@bandit:~$ ls
inhere

bandit4@bandit:~$ file inhere/*


inhere/-file00: data
inhere/-file01: data
inhere/-file02: data
inhere/-file03: data
inhere/-file04: data
inhere/-file05: data
inhere/-file06: data
inhere/-file07: ASCII text
inhere/-file08: data
inhere/-file09: data

bandit4@bandit:~$ pwd 

/home/bandit4

bandit4@bandit:~$ cat /home/bandit4/inhere/-file07

koReBOKuIDDepwhWk7jZC0RTdopnAYKh
bandit4@bandit:~$ 
0
user234732

Vous pouvez essayer ceci

find . -size 1033c ! -executable -exec file {} +

Votre défi ne permet pas grep. Le fichier de mot de passe sera signalé comme "Texte ASCII, avec de très longues lignes"

0
Emmanuel
find . -size 1033c ! -executable|xargs file|grep "ASCII text" |awk -F: '{print $1}'

Veuillez essayer ces commandes combinées. cela fonctionne sur ma station.

0
Fengbo Wu
find . -type f -size 1033c ! -executable | xargs file | grep text

Fan d'une doublure

0
Dark Knight

Je pense que la manière la plus longue de trouver le mot de passe pour ce niveau de bandit mentionné par la plupart ci-dessus en utilisant find et grep est la commande la plus descriptive.

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

Mais, après avoir utilisé la commande 'file' plus, j'ai réalisé qu'il était assez facile de localiser les fichiers lisibles par l'homme (aka ASCII à ce niveau) de cette façon en vérifiant les types de fichiers d'un répertoire entier. Le répertoire inhere contient des fichiers avec le nom '-filexx' ou vérifiez rapidement l'ensemble du répertoire inhere avec file ./*

Voici mon approche.

bandit4@bandit:~/inhere$ file ./*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data

bandit4@bandit:~/inhere$ cat ./-file07
koReBOKuIDDepwhWk7jZC0RTdopnAYKh
0
Tanner Dolby
find  -type f ! -executable -size 1033c

vous obtiendrez le fichier de l'exercice

0
coolhand

Pour filtrer les noms de fichiers lisibles par l'homme, vous pouvez utiliser le [:print:] ( imprimable ) classe de caractères nom. Vous trouverez plus d'informations sur ces classes dans le manuel de grep.

find . -type f -size 1033c -name "[[:print:]]*" ! -executable

Dans un second temps, l'exigence "lisible par l'homme" pourrait faire référence au contenu du fichier, au lieu de son nom. En d'autres termes, vous recherchez des fichiers texte . C'est un peu plus délicat. Comme l'a suggéré @D_Bye dans un commentaire, vous devez ensuite utiliser la commande file pour déterminer le type de contenu du fichier. Mais ce ne serait pas une bonne idée d'exécuter file après un pipe, car cela compliquerait la tâche d'afficher le nom du fichier. Voici ce que je suggère:

find . -type f -size 1033c ! -executable -exec sh -c 'file -b $0 | grep -q text' {} \; -print

Voici brièvement comment fonctionne la partie file-:

  • Le prédicat -exec exécute sh -c 'file -b $0 | grep -q text' FILENAME Pour chaque FILENAME qui satisfait toutes les conditions précédentes (type, taille, non exécutable).
  • Pour chacun de ces fichiers, un Shell (sh) exécute ce court script: file -b $0 | grep -q text, En remplaçant $0 Par le nom du fichier.
  • Le programme file détermine le type de contenu de chaque fichier et génère ces informations. L'option -b Empêche d'imprimer le nom de chaque fichier testé.
  • grep filtre la sortie provenant du programme file, recherchant les lignes contenant "texte" . (Voyez par vous-même à quoi ressemble une sortie typique de la commande file.)
  • Mais grep ne produit pas le texte filtré, car il a l'option -q (silencieux) donnée. Ce qu'il fait, c'est simplement changer son état de sortie en 0 (Qui représente "vrai" - le texte filtré a été trouvé) ou 1 (signifiant "erreur" - le texte "texte" n'apparaissait pas dans la sortie de file).
  • Le statut de sortie vrai/faux provenant de grep est transmis plus loin par sh à find et agit comme le résultat final de l'ensemble du test "-exec sh -c 'file $0 | grep -q text' {} \;".
  • Si le test ci-dessus renvoie vrai , la commande -print Est exécutée (c'est-à-dire que le nom du fichier testé est imprimé).
0
Alfran