Debian Bug report logs -
#1031267
debmany: CVE-2023-27635: shell injection
Reported by: Jakub Wilk <jwilk@jwilk.net>
Date: Tue, 14 Feb 2023 09:57:01 UTC
Severity: normal
Tags: confirmed, patch, pending, security
Found in version debian-goodies/0.88.1
Reply or subscribe to this bug.
Toggle useless messages
Report forwarded
to debian-bugs-dist@lists.debian.org, jwilk@jwilk.net, Javier Fernández-Sanguino Peña <jfs@debian.org>
:
Bug#1031267
; Package debian-goodies
.
(Tue, 14 Feb 2023 09:57:03 GMT) (full text, mbox, link).
Message #3 received at submit@bugs.debian.org (full text, mbox, reply):
[Message part 1 (text/plain, inline)]
Package: debian-goodies
Version: 0.88.1
Tags: security
debmany passes filenames from the .deb (which should be considered
untrusted input) to eval.
I've attached proof-of-concept exploit.
--
Jakub Wilk
[injection.deb (application/vnd.debian.binary-package, attachment)]
Information forwarded
to debian-bugs-dist@lists.debian.org, Javier Fernández-Sanguino Peña <jfs@debian.org>
:
Bug#1031267
; Package debian-goodies
.
(Tue, 14 Feb 2023 10:06:07 GMT) (full text, mbox, link).
Message #6 received at 1031267@bugs.debian.org (full text, mbox, reply):
* Jakub Wilk <jwilk@jwilk.net>, 2023-02-14 10:53:
>attached proof-of-concept exploit.
The code that generated the crafted .deb is here:
https://github.com/jwilk/crafted.deb/blob/master/gen-deb1031267-debmany
--
Jakub Wilk
Information forwarded
to debian-bugs-dist@lists.debian.org, Javier Fernández-Sanguino Peña <jfs@debian.org>
:
Bug#1031267
; Package debian-goodies
.
(Tue, 14 Feb 2023 14:57:02 GMT) (full text, mbox, link).
Acknowledgement sent
to Axel Beckert <abe@debian.org>
:
Extra info received and forwarded to list. Copy sent to Javier Fernández-Sanguino Peña <jfs@debian.org>
.
(Tue, 14 Feb 2023 14:57:03 GMT) (full text, mbox, link).
Message #11 received at 1031267@bugs.debian.org (full text, mbox, reply):
[Message part 1 (text/plain, inline)]
Control: tag -1 + confirmed
Hi Jakub,
thanks for the bug report.
Jakub Wilk wrote:
> debmany passes filenames from the .deb (which should be considered untrusted
> input) to eval.
>
> I've attached proof-of-concept exploit.
Thanks. Can reproduce it.
Given that the full path including the exploit code is always shown to
the user before the exploit actually runs, I consider the impact
rather low:
┌────────────────────────┤ Select a file (file:./injection.deb) ├────────────────────────┐
│ │
│ usr/share/doc/$(cowsay${IFS}pwned>/dev/tty;sleep${IFS}inf)/changelog.gz changelog.gz │
│ │
│ <Ok> <Cancel> │
│ │
└────────────────────────────────────────────────────────────────────────────────────────┘
Accordingly a severity of only "normal" seems fitting.
Should be fixed nevertheless. Will look into it.
Regards, Axel
--
,''`. | Axel Beckert <abe@debian.org>, https://people.debian.org/~abe/
: :' : | Debian Developer, ftp.ch.debian.org Admin
`. `' | 4096R: 2517 B724 C5F6 CA99 5329 6E61 2FF9 CD59 6126 16B5
`- | 1024D: F067 EA27 26B9 C3FC 1486 202E C09E 1D89 9593 0EDE
[signature.asc (application/pgp-signature, inline)]
Added tag(s) confirmed.
Request was from Axel Beckert <abe@debian.org>
to 1031267-submit@bugs.debian.org
.
(Tue, 14 Feb 2023 14:57:03 GMT) (full text, mbox, link).
Information forwarded
to debian-bugs-dist@lists.debian.org, Javier Fernández-Sanguino Peña <jfs@debian.org>
:
Bug#1031267
; Package debian-goodies
.
(Sun, 19 Feb 2023 04:51:03 GMT) (full text, mbox, link).
Acknowledgement sent
to Axel Beckert <abe@debian.org>
:
Extra info received and forwarded to list. Copy sent to Javier Fernández-Sanguino Peña <jfs@debian.org>
.
(Sun, 19 Feb 2023 04:51:03 GMT) (full text, mbox, link).
Message #18 received at 1031267@bugs.debian.org (full text, mbox, reply):
Control: tag -1 + patch pending
Hi Jakub,
found time to analyse this closer.
Axel Beckert wrote:
> Given that the full path including the exploit code is always shown to
> the user before the exploit actually runs, I consider the impact
> rather low:
>
> ┌────────────────────────┤ Select a file (file:./injection.deb) ├────────────────────────┐
> │ │
> │ usr/share/doc/$(cowsay${IFS}pwned>/dev/tty;sleep${IFS}inf)/changelog.gz changelog.gz │
> │ │
> │ <Ok> <Cancel> │
> │ │
> └────────────────────────────────────────────────────────────────────────────────────────┘
And this even though $manpages (which holds a space separated list of
all files to offer) is — on purpose — unquoted when passing to the
selection program.
But the real culprit is the use of eval in lines 415, 422 and 424:
414 debug "Opening manpage file: "`printf "$mancmdline" "$PWD/$file"` # comment
415 eval $(printf "$mancmdline" "$PWD/$file")
416 cd - >/dev/null
417 else
418 # other file (usr/share/doc)
419 debug "Opening other file: "`printf "$othercmdline" "$PWD/$return"` # comment
420 if [[ "$return" =~ \.gz$ ]]
421 then
422 eval $(printf "gzip -dc $PWD/$return | $othercmdline")
423 else
424 eval $(printf "$othercmdline" "$PWD/$return")
425 fi
Eval is evil. Once again.
My first thought was to just exclude all files with shell special
characters, especially '$(' and friends. But
apt-file search -n \$\( | fgrep /usr/share/doc/
shows that these are actually used (and fail with debmany due to the
issue reported by Jakub):
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Maths/hex$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/chr$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/insert$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/lCase$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/lTrim$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/left$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/mid$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/replace$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/replaceSubstr$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/reverse$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/right$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/space$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/str$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/string$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/trim$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/typeOf$().html
sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/uCase$().html
Additionally there are tons of files with just $ or any kind of brackets.
Just quoting them "properly" inside the eval and printf won't help as
you can always escape from there by just ending the according
quotation by adding a closing quote character into your file path.
In case of the ".gz" case in your example, it's easier to fix as you
can simply move "gzip -dc $PWD/$return |" out of the eval/printf.
But in the other cases it's less simple.
So I came up with the following fix which uses command instead of
eval, and bash pattern substitution to replace %s with the file name
instead letting printf inside an $() doing the substitution:
diff --git a/debmany/debmany b/debmany/debmany
index 7eeb68b..dfea6e9 100755
--- a/debmany/debmany
+++ b/debmany/debmany
@@ -96,6 +96,19 @@ Examples: debmany foo.deb show manpages from a local package file foo.deb
fi
}
+replace_percent_s_and_execute() {
+ replacement="$1"
+ shift
+ declare -a cmdarr
+ cmdarr=($@)
+ debug "cmdarr before; ${cmdarr[@]}"
+ for i in ${!cmdarr[@]}; do
+ cmdarr[$i]="${cmdarr[$i]/\%s/$replacement}"
+ done
+ debug "cmdarr after; ${cmdarr[@]}"
+ command "${cmdarr[@]}"
+}
+
while [ $# -gt 0 ]
do
case $1 in
@@ -377,6 +390,7 @@ else
dpkg --fsys-tarfile "$file" | tar --wildcards -xf - $mandirs 2>/dev/null
# find all manpage files
manpages=`find usr -type f 2>/dev/null|sort|sed -e 's|\([^/]*\)$|\1 \1|'`
+ # | egrep -v '[\`\\${}*?;<>|]'
fi
while true
@@ -412,16 +426,16 @@ do
cd "$path"
fi
debug "Opening manpage file: "`printf "$mancmdline" "$PWD/$file"` # comment
- eval $(printf "$mancmdline" "$PWD/$file")
+ replace_percent_s_and_execute "$PWD/$file" "$mancmdline"
cd - >/dev/null
else
# other file (usr/share/doc)
debug "Opening other file: "`printf "$othercmdline" "$PWD/$return"` # comment
if [[ "$return" =~ \.gz$ ]]
then
- eval $(printf "gzip -dc $PWD/$return | $othercmdline")
+ gzip -dc "$PWD/$return" | replace_percent_s_and_execute '-' "$othercmdline"
else
- eval $(printf "$othercmdline" "$PWD/$return")
+ replace_percent_s_and_execute "$PWD/$return" "$othercmdline"
fi
fi
else
This is now committed as
https://salsa.debian.org/debian/debian-goodies/-/commit/495eaafa94d2b4cbee4eed01cd78238e311d096b
but I'd be happy about a review before I upload.
I will also do some more testing on my side.
Regards, Axel
--
,''`. | Axel Beckert <abe@debian.org>, https://people.debian.org/~abe/
: :' : | Debian Developer, ftp.ch.debian.org Admin
`. `' | 4096R: 2517 B724 C5F6 CA99 5329 6E61 2FF9 CD59 6126 16B5
`- | 1024D: F067 EA27 26B9 C3FC 1486 202E C09E 1D89 9593 0EDE
Added tag(s) patch and pending.
Request was from Axel Beckert <abe@debian.org>
to 1031267-submit@bugs.debian.org
.
(Sun, 19 Feb 2023 04:51:03 GMT) (full text, mbox, link).
Information forwarded
to debian-bugs-dist@lists.debian.org, Javier Fernández-Sanguino Peña <jfs@debian.org>
:
Bug#1031267
; Package debian-goodies
.
(Mon, 06 Mar 2023 04:57:03 GMT) (full text, mbox, link).
Acknowledgement sent
to Salvatore Bonaccorso <carnil@debian.org>
:
Extra info received and forwarded to list. Copy sent to Javier Fernández-Sanguino Peña <jfs@debian.org>
.
(Mon, 06 Mar 2023 04:57:03 GMT) (full text, mbox, link).
Message #25 received at 1031267@bugs.debian.org (full text, mbox, reply):
Control: retitle -1 debmany: CVE-2023-27635: shell injection
On Sun, Feb 19, 2023 at 05:47:20AM +0100, Axel Beckert wrote:
> Control: tag -1 + patch pending
>
> Hi Jakub,
>
> found time to analyse this closer.
>
> Axel Beckert wrote:
> > Given that the full path including the exploit code is always shown to
> > the user before the exploit actually runs, I consider the impact
> > rather low:
> >
> > ┌────────────────────────┤ Select a file (file:./injection.deb) ├────────────────────────┐
> > │ │
> > │ usr/share/doc/$(cowsay${IFS}pwned>/dev/tty;sleep${IFS}inf)/changelog.gz changelog.gz │
> > │ │
> > │ <Ok> <Cancel> │
> > │ │
> > └────────────────────────────────────────────────────────────────────────────────────────┘
>
> And this even though $manpages (which holds a space separated list of
> all files to offer) is — on purpose — unquoted when passing to the
> selection program.
>
> But the real culprit is the use of eval in lines 415, 422 and 424:
>
> 414 debug "Opening manpage file: "`printf "$mancmdline" "$PWD/$file"` # comment
> 415 eval $(printf "$mancmdline" "$PWD/$file")
> 416 cd - >/dev/null
> 417 else
> 418 # other file (usr/share/doc)
> 419 debug "Opening other file: "`printf "$othercmdline" "$PWD/$return"` # comment
> 420 if [[ "$return" =~ \.gz$ ]]
> 421 then
> 422 eval $(printf "gzip -dc $PWD/$return | $othercmdline")
> 423 else
> 424 eval $(printf "$othercmdline" "$PWD/$return")
> 425 fi
>
> Eval is evil. Once again.
>
> My first thought was to just exclude all files with shell special
> characters, especially '$(' and friends. But
>
> apt-file search -n \$\( | fgrep /usr/share/doc/
>
> shows that these are actually used (and fail with debmany due to the
> issue reported by Jakub):
>
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Maths/hex$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/chr$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/insert$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/lCase$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/lTrim$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/left$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/mid$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/replace$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/replaceSubstr$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/reverse$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/right$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/space$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/str$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/string$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/trim$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/typeOf$().html
> sdlbasic: /usr/share/doc/sdlbasic/english/sections/commands/Strings/uCase$().html
>
> Additionally there are tons of files with just $ or any kind of brackets.
>
> Just quoting them "properly" inside the eval and printf won't help as
> you can always escape from there by just ending the according
> quotation by adding a closing quote character into your file path.
>
> In case of the ".gz" case in your example, it's easier to fix as you
> can simply move "gzip -dc $PWD/$return |" out of the eval/printf.
>
> But in the other cases it's less simple.
>
> So I came up with the following fix which uses command instead of
> eval, and bash pattern substitution to replace %s with the file name
> instead letting printf inside an $() doing the substitution:
>
> diff --git a/debmany/debmany b/debmany/debmany
> index 7eeb68b..dfea6e9 100755
> --- a/debmany/debmany
> +++ b/debmany/debmany
> @@ -96,6 +96,19 @@ Examples: debmany foo.deb show manpages from a local package file foo.deb
> fi
> }
>
> +replace_percent_s_and_execute() {
> + replacement="$1"
> + shift
> + declare -a cmdarr
> + cmdarr=($@)
> + debug "cmdarr before; ${cmdarr[@]}"
> + for i in ${!cmdarr[@]}; do
> + cmdarr[$i]="${cmdarr[$i]/\%s/$replacement}"
> + done
> + debug "cmdarr after; ${cmdarr[@]}"
> + command "${cmdarr[@]}"
> +}
> +
> while [ $# -gt 0 ]
> do
> case $1 in
> @@ -377,6 +390,7 @@ else
> dpkg --fsys-tarfile "$file" | tar --wildcards -xf - $mandirs 2>/dev/null
> # find all manpage files
> manpages=`find usr -type f 2>/dev/null|sort|sed -e 's|\([^/]*\)$|\1 \1|'`
> + # | egrep -v '[\`\\${}*?;<>|]'
> fi
>
> while true
> @@ -412,16 +426,16 @@ do
> cd "$path"
> fi
> debug "Opening manpage file: "`printf "$mancmdline" "$PWD/$file"` # comment
> - eval $(printf "$mancmdline" "$PWD/$file")
> + replace_percent_s_and_execute "$PWD/$file" "$mancmdline"
> cd - >/dev/null
> else
> # other file (usr/share/doc)
> debug "Opening other file: "`printf "$othercmdline" "$PWD/$return"` # comment
> if [[ "$return" =~ \.gz$ ]]
> then
> - eval $(printf "gzip -dc $PWD/$return | $othercmdline")
> + gzip -dc "$PWD/$return" | replace_percent_s_and_execute '-' "$othercmdline"
> else
> - eval $(printf "$othercmdline" "$PWD/$return")
> + replace_percent_s_and_execute "$PWD/$return" "$othercmdline"
> fi
> fi
> else
>
> This is now committed as
> https://salsa.debian.org/debian/debian-goodies/-/commit/495eaafa94d2b4cbee4eed01cd78238e311d096b
> but I'd be happy about a review before I upload.
>
> I will also do some more testing on my side.
The issue itself has CVE-2023-27635 now.
Jakub, were you able to peer review Axel's approach?
Axel, on the severity, I do not believe this will warrant a DSA. It is
sufficiently guarded already as the user will be prompted before
execution with the path.
Regards,
Salvatore
Changed Bug title to 'debmany: CVE-2023-27635: shell injection' from 'debmany: shell injection'.
Request was from Salvatore Bonaccorso <carnil@debian.org>
to 1031267-submit@bugs.debian.org
.
(Mon, 06 Mar 2023 04:57:03 GMT) (full text, mbox, link).
Send a report that this bug log contains spam.
Debian bug tracking system administrator <owner@bugs.debian.org>.
Last modified:
Mon Mar 6 13:08:02 2023;
Machine Name:
buxtehude
Debian Bug tracking system
Debbugs is free software and licensed under the terms of the GNU
Public License version 2. The current version can be obtained
from https://bugs.debian.org/debbugs-source/.
Copyright © 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson,
2005-2017 Don Armstrong, and many other contributors.