Bandit 9 → 10: readable text in a binary file
First level where the file isn’t meant to be read at all. Two filters, one after the other: pull out the parts that are text, then keep the ones that are marked.
the goal
The password for the next level is stored in the file
data.txtin one of the few human-readable strings, preceded by several=characters.
the approach
cat data.txt
Garbage. The file is mostly binary, so cat throws a screenful of nonsense at the
terminal and beeps at you. But the objective says there is readable text in
there, and that it’s marked — several = characters sit in front of it.
strings is the tool for the first half. It walks a file and prints any run of
printable characters long enough to look like text, ignoring everything else. So
the job is: run that, then keep only the lines carrying the = marker.
strings data.txt | while read -r line; do
case "$line" in
*=*) echo "$line" ;;
esac
done
That prints a handful of lines rather than one. Several contain = signs and only
one is the password — obvious on sight, because the others are fragments and it’s
a clean 32-character string.
Worth naming why: “contains an =” is a much weaker test than “starts with
several = then a run of letters and digits.” The loose filter makes you pick;
the tight one wouldn’t.
the takeaway
strings is how you look inside a file that isn’t text. Binaries, memory
dumps, disk images, a file you can’t identify — strings pulls the human-readable
runs out and throws the rest away. It’s the first thing to reach for when cat
gives you garbage.
The pipe version of that loop:
strings data.txt | grep '='
Same result, one line. And the tight version:
strings data.txt | grep -E '^=+[A-Za-z0-9]+$'
^=+ — starts with one or more =. [A-Za-z0-9]+$ — then letters and digits to
the end of the line, nothing else. That describes the thing you’re looking for
rather than something it happens to contain, which is the whole difference between
a filter that narrows and a filter that nearly narrows.