Pwn De Ring

初心者がPwnを勉強していくために使っている標準出力先です。

/proc/self/auxvを用いたCanaryリーク

tl;dr

/proc/self/auxvから見れるAT_RANDOMの値が指すメモリの値の末尾1byteを0x00に変更したものがCanaryと等しい。

はじめに

/proc配下にはexploitする上で良い情報源となる物が多い。今回はそれらの中でもauxv(auxiliary vector補助ベクトルの略かな?)に注目する。auxvには、実行時にプロセスに渡された ELF インタープリター情報が格納されている。具体的にはunsigned longのidとidに対応するunsigned longなvalueが格納されている。ここに格納されている情報を用いてCanaryをリークする。

環境

どういう環境でこれが成立するのかわからないので、とりあえず試した環境を示しておく。

vagrant@ubuntu4ctf ~/c/t/auxv> uname -a                                                                                                               
Linux ubuntu4ctf 4.8.0-32-generic #34~16.04.1-Ubuntu SMP Tue Dec 13 17:03:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
vagrant@ubuntu4ctf ~/c/t/auxv> cat /etc/lsb-release                                                                                                   
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.2 LTS"
vagrant@ubuntu4ctf ~/c/t/auxv> gcc --version                                                                                                          
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

vagrant@ubuntu4ctf ~/c/t/auxv> /lib/x86_64-linux-gnu/libc.so.6                                                                                        
GNU C Library (Ubuntu GLIBC 2.23-0ubuntu9) stable release version 2.23, by Roland McGrath et al.
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 5.4.0 20160609.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
libc ABIs: UNIQUE IFUNC
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.

/proc/self/auxvを見てみる

簡単に見る方法として、環境変数LD_SHOW_AUXV=1をセットしておくことで、/proc/self/auxvの値をidとvalueのペアでわかりやすいように表示してくれる。

試しに/bin/lsを実行してみる。

vagrant@ubuntu4ctf:~/ctf/tmp/auxv$ LD_SHOW_AUXV=1 /bin/ls
AT_SYSINFO_EHDR: 0x7ffcac3e6000
AT_HWCAP:        78bfbff
AT_PAGESZ:       4096
AT_CLKTCK:       100
AT_PHDR:         0x400040
AT_PHENT:        56
AT_PHNUM:        9
AT_BASE:         0x7f0195d8d000
AT_FLAGS:        0x0
AT_ENTRY:        0x4049a0
AT_UID:          1000
AT_EUID:         1000
AT_GID:          1000
AT_EGID:         1000
AT_SECURE:       0
AT_RANDOM:       0x7ffcac339899
AT_EXECFN:       /bin/ls
AT_PLATFORM:     x86_64
getauxval_test.c

他にも、glibcがauxiliary vectorから値を取得するgetauxval関数も存在する。以下にサンプルプログラムを示す。

/*
 * gcc getauxval_test.c
 */
#include <stdio.h>
#include <sys/auxv.h>
int main(int argc, char* argv[]) {

  printf("AT_PLATFORM: %s\n", getauxval(AT_PLATFORM));
  printf("AT_RANDOM: %lx\n", getauxval(AT_RANDOM));

  return 0;
}

実行してみるとこんか感じ。

vagrant@ubuntu4ctf ~/c/t/auxv> ./a.out                                                                       
AT_PLATFORM: x86_64
AT_RANDOM: 7fffedf92c29

Canaryをリークしてみる

実はこのAT_RANDOMが指すメモリの値に、Canaryと末尾1byteのみが異なる値が格納されている。また、Canaryは末尾1byteが0x00だと既知なので、実質Canaryが求まることになる。 実際に求めるプログラムを以下に示す。

/*
 * gcc canary_leak_from_auxv.c
 */
#include <stdio.h>
#include <sys/auxv.h>

int main(int argc, char* argv[]) {
  char buf[16]
  unsigned long *canary_addr = (unsigned long*)getauxval(AT_RANDOM);
  unsigned long canary;
  canary = (unsigned long*)*canary_addr;
  canary &= ~0xff; // 末尾1byteを0x00に
  printf("Canary: 0x%lx\n", canary);

  return 0;
}

上記のプログラムをコンパイルしたら、実際にgdbでCanaryの値とprintfする際の第二引数を見てCanaryの値が一致しているかをたしかめてみる。最初のスクショがCanaryをraxレジスタに入れた直後で、二つ目がprintfを呼ぶ直前の画面である。f:id:encry1024:20170812001930p:plain f:id:encry1024:20170812001956p:plain

これらの結果からCanaryが一致していることがわかる。

まとめ

以下の2点が揃えばCanaryをリークすることが可能である。

  • /proc/self/auxvかgetauxval関数が呼べる
  • メモリのread、writeができる

感想

上記の2つが出来てたら、もうCanaryをリークする意味はなさそう…w