Jag försöker hitta ett effektivt sätt att göra nivå 5 i OverTheWire-banditutmaningen .
Hur som helst, jag har en massa filer, och det finns bara en som respekterar följande kriterier:
- Mänsklig
- 1033 byte i storlek
- Ej körbar
Just nu använder jag kommandot find
, och jag kan hitta filerna som matchar de två sista kriterierna:
find . -size 1033c ! -executable
Jag vet dock inte hur man kan utesluta icke-läsbara filer Lösningar som jag hittade för den utmaningen använder testparametern -readable
, men jag tycker inte att det fungerar. -readable
tittar bara på filernas behörigheter och inte på dess innehåll, medan utmaningsbeskrivningen ber om en ASCII-fil eller något liknande.
Kommentarer
- Hur definierar du mänskligt läsbart? Inte binärt?
- filkommandot är din vän 🙂
- Kanske duplikat av: stackoverflow.com/questions/14505218/…
- Människor är en av de mest intelligenta kända arterna på jorden. De ’ är också de enda kända för datorer. De kan läsa de flesta filer förutsatt att de kan ta reda på typen och få tag i krypteringsnycklarna för krypterad.
- SPOILER ALERT !!
Svar
Ja, du kan använda find
för att leta efter icke-körbara filer av rätt storlek och använd sedan file
för att söka efter ASCII. Något som:
find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII
Questi på är dock inte så enkelt som det låter. ”Mänskligt läsbart” är en fruktansvärt vag term. Förmodligen menar du text. OK, men vilken typ av text? Latinsk karaktär endast ASCII? Full Unicode? Tänk till exempel på dessa tre filer:
$ cat file1 abcde $ cat file2 αβγδε $ cat file3 abcde αβγδε $ cat file4 #!/bin/sh echo foo
Allt detta är text och läsbart för människor. Låt oss nu se vad file
gör av dem:
$ file * file1: ASCII text file2: UTF-8 Unicode text file3: UTF-8 Unicode text file4: POSIX shell script, ASCII text executable
Så, find
-kommandot ovan hittar bara file1
(för exemplets skull, låt oss föreställa oss att filerna hade 1033 tecken). Du kan utöka find
för att leta efter strängen text
:
find . -type f -size 1033c ! -executable -exec file {} + | grep -w text
Med -w
skriver grep
bara rader där text
finns som ett fristående ord. Det ska vara ganska nära det du vill, men jag kan inte garantera att det inte finns någon annan filtyp vars beskrivning också kan innehålla strängen text
.
Svar
Medan -exec
oftast används för att göra något med filerna som där det finns kan det också fungera som ett test. Därför kan vi lägga till det i dina andra kriterier:
find . \ -size 1033c \ -not -executable \ -exec sh -c "file {} | grep "text$"" \;
Kom ihåg, grep
returnerar icke-noll när mönstret inte hittades, och sh -c "COMMAND"
returnerar utvärderingsresultatet (så länge det är giltigt). skriv bara ut filer där file <filename>
spottar något som slutar med text
, t.ex. ”UTF-8 Unicode-text” eller ”ASCII-text”, men inte ”Icke-ISO-utökad ASCII-text, med escape-sekvenser”.
På en enda rad hamnar den till och med kortare än att gå över xargs
:
find . -size 1033c -not -executable -exec sh -c "file {} | grep "text$"" \;
Håll i tänk på att du kan ersätta sh -c "file {} | grep "text$""
med valfritt anpassat kommando. Om du vill söka efter något väldigt komplext kan det vara en bättre idé att tillhandahålla ett skalskript och använda det istället:
find . -size 1033c -not -executable -exec is_human_readable.sh {} \;
som på lång sikt kör, är lättare att underhålla än din skalhistorik:
#!/bin/sh file "$@" | grep "text$" > /dev/null
Kommentarer
- Trevligt! Observera dock att matchning av
text$
utesluter saker som känns igen som skalskript. Allt med en shebang identifieras som ett manus och de är helt mänskliga läsbara. - @terdon sant, men skript tenderar att vara körbara: D. Med detta sagt bör ett korrekt skript också känna igen PDF-filer. Men å andra sidan, är en PDF som innehåller en bild mänsklig läsbar ? Är en PNG av någon text läsbar ? Antagligen. Jag antar att ett fullständigt test kommer att vara … utmanande.
Svar
Du behöver bara använda:
find inhere -size 1033c
Det ger dig den enda filen som innehåller lösenordet.
Kommentarer
- varför returnerar + 1033c fler filer? är det som ett större eller lika tecken?
Svar
find . -size 1033c ! -executable -exec file {} +
Svar
Kör bara följande mot innehållet i katalogen:
$ 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>
Svar
Det finns bara 1 fil med 1033
byte i storlek.
bandit5@bandit:~$ find -size 1033c ./inhere/maybehere07/.file2 bandit5@bandit:~$
Varför 1033c
och inte 1033
? Kontrollera man
sidan
-size n[cwbkMG] File uses n units of space, rounding up. The following suffixes can be used: `b" for 512-byte blocks (this is the default if no suffix is used) `c" for bytes `w" for two-byte words `k" for Kilobytes (units of 1024 bytes) `M" for Megabytes (units of 1048576 bytes) `G" for Gigabytes (units of 1073741824 bytes)
Verifiera det med kommandot ls -l
och file
så får du allt svar.
bandit5@bandit:~$ ls -l ./inhere/maybehere07/.file2 -rw-r----- 1 root bandit5 1033 May 7 20:15 ./inhere/maybehere07/.file2 bandit5@bandit:~$ bandit5@bandit:~$ file ./inhere/maybehere07/.file2 ./inhere/maybehere07/.file2: ASCII text, with very long lines bandit5@bandit:~$
- läsbart för människor (
ASCII text
) - 1033 byte i storlek (även i
ls -l
output) - inte körbar (
-rw-r-----
)
Svar
find . -size 1033c ! -executable|xargs file|grep "ASCII text" |awk -F: "{print $1}"
Försök med de här kombinerade kommandona. det fungerar på min station.
Svar
Du kan prova detta
find . -size 1033c ! -executable -exec file {} +
Din utmaning tillåter inte grep
. lösenordsfil kommer att rapporteras som ”ASCII-text, med mycket långa rader”
Svar
För att filtrera bort mänskligt läsbara filnamn, du kan använda [:print:]
( utskrivbar ) teckenklass namn. Du hittar mer om sådana klasser i handboken för grep
.
find . -type f -size 1033c -name "[[:print:]]*" ! -executable
På en andra tanke , kan ”mänskligt läsbart” krav hänvisa till filens innehåll istället för dess namn. Med andra ord skulle du söka efter text filer. Det är lite mer knepigt. Som @ D_Bye föreslog i en kommentar, använd sedan kommandot file
för att bestämma filinnehållstypen. Men det skulle inte vara en bra idé att köra file
efter ett rör, eftersom det skulle komplicera uppgiften att visa filens namn. Här är vad jag föreslår:
find . -type f -size 1033c ! -executable -exec sh -c "file -b $0 | grep -q text" {} \; -print
Så här fungerar file
-delen:
-
-exec
predikat utförsh -c "file -b $0 | grep -q text" FILENAME
för varjeFILENAME
som uppfyller alla tidigare villkor (typ, storlek, ej körbar). - För var och en av dessa filer , ett skal (
sh
) kör detta korta skript :file -b $0 | grep -q text
, ersätter$0
med filnamnet. -
file
bestämmer innehållstypen för varje fil och matar ut denna information. Alternativet-b
förhindrar utskrift av Namn på varje testad fil. -
grep
filter produktionen kommer från
program, söker efter rader som innehåller ”text” . (Se själv hur en typisk utgång frånfile
ser ut.)
grep
mata ut den filtrerade texten, för den har -q
(tyst) alternativet ges . Vad den gör är att bara ändra utgångsstatus till antingen 0
(vilket representerar ”sant” – den filtrerade texten hittades) eller 1 (vilket betyder ”fel ”- texten ” text ” visas inte i utdata från file
). grep
skickas vidare av sh
till find
och fungerar som slutresultatet av helheten ”-exec sh -c "file $0 | grep -q text" {} \;
” test. -print
kommandot körs (dvs. namnet på den testade filen skrivs ut). Svar
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:~$
Kommentarer
- Använd bara filen inhere / * och cat / home / bandit4 / inhere / -file07
Svar
find -type f ! -executable -size 1033c
ger dig filen från övningen
Svara
find . -type f -size 1033c ! -executable | xargs file | grep text
Fläkt av en linje
Svar
Jag tror att det längre beskrivningen av lösenordet för denna banditnivå som nämns av de flesta ovan med hjälp av find och grep är det mest beskrivande kommandot.
find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII
Men efter att ha använt kommandot ”file” mer insåg jag att det är ganska lätt att hitta mänskliga läsbara filer (aka ASCII på den här nivån) på detta sätt genom att kontrollera en hel katalogtyp.Inhere-katalogen innehåller filer med namnet ”-filexx” eller kolla snabbt hela inhere-katalogen med file ./*
Här var mitt tillvägagångssätt.
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