Bash Child/Parent 管道继承漏洞利用
Bash Child/Parent Pipe Inheritance Exploit
#!/bin/bash
ipaddr=
rdlnk=$(readlink /proc/$$/fd/0)
user=""
passwd=""
function get_input() {
if grep -Eq "^pipe:|deleted" <<< "${rdlnk}" || [[ -p "${rdlnk}" ]]; then
while IFS= read -r piped_input || break; do
[[ -z "${ipaddr}" ]] && ipaddr="${piped_input}" && continue
[[ -z "${user}" ]] && user="${piped_input}" && continue
[[ -z "${passwd}" ]] && passwd="${piped_input}" && continue
done
fi
echo "Got that IP address you gave me to work on: ${ipaddr}"
[[ -n "${user}" ]] && echo "[... and that user: ${user}]"
[[ -n "${user}" ]] && echo "[... and that users password: ${passwd}]"
}
get_input
exit 0
一般没问题:
$> process_ip.bsh 71.123.123.3
Got that IP address you gave me to work on: 71.123.123.3
但是,将 parent 放入管道循环中并注意:
$ echo -en "71.123.123.3\nroot\ntoor\n" | while read a; do echo "Parent loop, processing: ${a}"; grep -q '^[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}' <<< "${a}" && ./process_ip.bsh "$a"; done
Parent loop, processing: 71.123.123.3
Got that IP address you gave me to work on: 71.123.123.3
[... and that user: root]
[... and that users password: toor]
哎呀。 parent 只想提供从其管道到 child 的 IP 地址。假设 parent 在派生到 child 进程时必须维护一个打开的管道,其中包含敏感数据。如何预防?
process_ip.bsh
,像任何其他进程一样,从其父进程继承其标准输入。这一行
rdlnk=$(readlink /proc/$$/fd/0)
并不完全按照您的想法行事。它仅包含父级用于标准输入的文件的名称,因为脚本从父级继承其标准输入。 ($$
是当前 shell 的进程 ID,因为 .process_ip.bsh
是一个单独的进程,而不仅仅是父进程启动的子 shell。)
如果您将输入重定向到 process_ip.bsh
,您可以完全控制它接收的内容。
while read a; do
echo "Parent loop, processing: ${a}"
grep -q '^[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}' <<< "${a}" &&
./process_ip.bsh "$a" < /dev/null
done <<EOF
71.123.123.3
root
toor
EOF
#!/bin/bash
ipaddr=
rdlnk=$(readlink /proc/$$/fd/0)
user=""
passwd=""
function get_input() {
if grep -Eq "^pipe:|deleted" <<< "${rdlnk}" || [[ -p "${rdlnk}" ]]; then
while IFS= read -r piped_input || break; do
[[ -z "${ipaddr}" ]] && ipaddr="${piped_input}" && continue
[[ -z "${user}" ]] && user="${piped_input}" && continue
[[ -z "${passwd}" ]] && passwd="${piped_input}" && continue
done
fi
echo "Got that IP address you gave me to work on: ${ipaddr}"
[[ -n "${user}" ]] && echo "[... and that user: ${user}]"
[[ -n "${user}" ]] && echo "[... and that users password: ${passwd}]"
}
get_input
exit 0
一般没问题:
$> process_ip.bsh 71.123.123.3
Got that IP address you gave me to work on: 71.123.123.3
但是,将 parent 放入管道循环中并注意:
$ echo -en "71.123.123.3\nroot\ntoor\n" | while read a; do echo "Parent loop, processing: ${a}"; grep -q '^[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}' <<< "${a}" && ./process_ip.bsh "$a"; done
Parent loop, processing: 71.123.123.3
Got that IP address you gave me to work on: 71.123.123.3
[... and that user: root]
[... and that users password: toor]
哎呀。 parent 只想提供从其管道到 child 的 IP 地址。假设 parent 在派生到 child 进程时必须维护一个打开的管道,其中包含敏感数据。如何预防?
process_ip.bsh
,像任何其他进程一样,从其父进程继承其标准输入。这一行
rdlnk=$(readlink /proc/$$/fd/0)
并不完全按照您的想法行事。它仅包含父级用于标准输入的文件的名称,因为脚本从父级继承其标准输入。 ($$
是当前 shell 的进程 ID,因为 .process_ip.bsh
是一个单独的进程,而不仅仅是父进程启动的子 shell。)
如果您将输入重定向到 process_ip.bsh
,您可以完全控制它接收的内容。
while read a; do
echo "Parent loop, processing: ${a}"
grep -q '^[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}' <<< "${a}" &&
./process_ip.bsh "$a" < /dev/null
done <<EOF
71.123.123.3
root
toor
EOF