質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.93%

gdbで見るlibcのアドレスと、lddコマンド+nmコマンドを使って計算したlibcのアドレスが違う

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,682

akamakku

score 193

ret2libcを再現してみようとしています。
※ASLRは無効になっています。

<前提>(セキュリティコンテストチャレンジブックを参考にしています)

//bof.c
#include <stdio.h>
#include <string.h>

char buffer[32];

int main(int argc, char const *argv[])
{
    char local[32];
    printf("buffer : 0x%x\n", &buffer);
    fgets(local, 128, stdin);
    strcpy(buffer, local);
    return 0;
}
$gcc -m32 -fno-stack-protector -o bof bof.c
  1. gdbを用いて、system関数のアドレスを調べる。
#出力を省略しています
$gdb -q bof
>b main
>r
>p system
$1 = {<text variable, no debug info>} 0xf7e53e10 <system>

gdbを用いてsystem関数のアドレスを調べた結果、0xf7e53e10でした。

2. ldd + nm を用いて、system関数のアドレスを計算する。

$ldd bof
    linux-gate.so.1 =>  (0xf7ffd000)
    libc.so.6 => /lib/libc.so.6 (0xf7e37000)
    /lib/ld-linux.so.2 (0x56555000)
$ldd bof
    linux-gate.so.1 =>  (0xf7ffd000)
    libc.so.6 => /lib/libc.so.6 (0xf7e37000)
    /lib/ld-linux.so.2 (0x56555000)


ASLRは無効になっており、libc.so.6は、0xf7e37000に配置されている。

$nm _D /lib/libc.so.6 | grep system
0003de10 T __libc_system
00127970 T svcerr_systemerr
0003de10 W system


libc内では、system関数は0x3de10に配置されている。

$ python -c 'print(hex(0xf7e37000+0x0003de10))'
0xf7e74e10


よって、メモリ上のsystem関数のアドレスは、0xf7e74e10

このように求まったアドレスが異なっています。

この2つのアドレスをそれぞれ使って、ret2libcをしてみたところ、
1.のアドレスはうまくいきましたが、2.のアドレスでは「Illegal instruction」と表示されうまくいきませんでした。

上記のコードでは、2つのアドレスが,0x21000だけずれていますが、
ちょっとコードを変えてやってみたのも、0x21000だけずれていました。

アドレス計算の方法が間違っているんでしょうか?

(追記)
配置されているアドレスと、ベースアドレスは別物なんでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

Ubuntu16.04 64ビット環境ですが、ldd <実行ファイル>ではなく、LD_TRACE_LOADED_OBJECTS=1 <実行ファイル>とやって、表示されたアドレスだと、計算が合いました。


gdbからでてきたアドレス (gdb) $1 = {<text variable, no debug info>} 0x7ffff7a53390 <__libc_system>と、$ADDR_LIBC + $OFFSET_SYSTEM => 0x7ffff7a53390からのアドレスが一致。

  • 確認例
mt08@u1604:~/teratail.com/questions/70098$ uname -a
Linux u1604 4.4.0-71-generic #92-Ubuntu SMP Fri Mar 24 12:59:01 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
mt08@u1604:~/teratail.com/questions/70098$ cat /etc/issue
Ubuntu 16.04.2 LTS \n \l

mt08@u1604:~/teratail.com/questions/70098$ # ASLRを無効にする
mt08@u1604:~/teratail.com/questions/70098$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
0
mt08@u1604:~/teratail.com/questions/70098$ ls -l
total 8
-rw-rw-r-- 1 mt08 mt08 240 Mar 31 07:55 bof.c
-rw-rw-r-- 1 mt08 mt08  22 Mar 31 07:58 gdb_cmd.txt
mt08@u1604:~/teratail.com/questions/70098$ cat bof.c
//bof.c
#include <stdio.h>
#include <string.h>

char buffer[32];

int main(int argc, char const *argv[])
{
    char local[32];
    printf("buffer : 0x%p\n", &buffer);
    fgets(local, 128, stdin);
    strcpy(buffer, local);
    return 0;
}
mt08@u1604:~/teratail.com/questions/70098$ cat gdb_cmd.txt
b main
r
p system
q
y
mt08@u1604:~/teratail.com/questions/70098$ gcc  -fno-stack-protector -o bof bof.c -g
mt08@u1604:~/teratail.com/questions/70098$ gdb -q ./bof < gdb_cmd.txt
Reading symbols from ./bof...done.
(gdb) Breakpoint 1 at 0x400605: file bof.c, line 10.
(gdb) Starting program: /home/mt08/teratail.com/questions/70098/bof 

Breakpoint 1, main (argc=1, argv=0x7fffffffe408) at bof.c:10
10        printf("buffer : 0x%p\n", &buffer);
(gdb) $1 = {<text variable, no debug info>} 0x7ffff7a53390 <__libc_system>
(gdb) A debugging session is active.

    Inferior 1 [process 18406] will be killed.

Quit anyway? (y or n) [answered Y; input not from terminal]
mt08@u1604:~/teratail.com/questions/70098$ LD_TRACE_LOADED_OBJECTS=1 ./bof
    linux-vdso.so.1 =>  (0x00007ffff7ffa000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7a0e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd7000)
mt08@u1604:~/teratail.com/questions/70098$ nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep ' system$'
0000000000045390 W system
mt08@u1604:~/teratail.com/questions/70098$ ADDR_LIBC=`LD_TRACE_LOADED_OBJECTS=1 ./bof | grep libc | perl -e '$str=<STDIN>; $str=~/\((.+)\)/;printf("%s\n",$1)'`
mt08@u1604:~/teratail.com/questions/70098$ OFFSET_SYSTEM=`nm -D /lib/x86_64-linux-gnu/libc.so.6 | grep ' system$' | perl -e '$str=<STDIN>;$str=~/^(.+) (.) /;printf("0x%s\n",$1)'`
mt08@u1604:~/teratail.com/questions/70098$ echo printf\(\"0x%x\\n\", $ADDR_LIBC + $OFFSET_SYSTEM\)
printf("0x%x\n", 0x00007ffff7a0e000 + 0x0000000000045390)
mt08@u1604:~/teratail.com/questions/70098$ echo printf\(\"0x%x\\n\", $ADDR_LIBC + $OFFSET_SYSTEM\) | perl
0x7ffff7a53390
mt08@u1604:~/teratail.com/questions/70098$ 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/05 15:03

    回答ありがとうございます。
    Man page of LDD には"ldd は標準の動的リンカー (ld.so(8) 参照) を LD_TRACE_LOADED_OBJECTS 環境変数に 1 をセットして起動する。 "と書いてあるのですが、
    lddとLD_TRACE_LOADED_OBJECTS=1はなにが違うんでしょうか?

    キャンセル

  • 2017/04/05 16:16

    Teppayさん、


    `ldd`は、shell scriptなので、中身をみて、追ってみるといいかと思います。
    ```
    mt08@linux64:~/teratail.com/questions/70098$ file `which ldd`
    /usr/bin/ldd: Bourne-Again shell script, ASCII text executable
    ```


    ちなみに、`echo` とかつっこんで、確認したところ、こちらの環境では、 `LD_TRACE_LOADED_OBJECTS=1 LD_WARN= LD_BIND_NOW= LD_LIBRARY_VERSION=$verify_out LD_VERBOSE= /lib64/ld-linux-x86-64.so.2 ./bof` という感じで、呼ばれてました。

    `/lib64/ld-linux-x86-64.so.2` がつくか、つかないかで、変わるみたいですね.

    ```
    mt08@linux64:~/teratail.com/questions/70098$ LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 ./bof
    linux-vdso.so.1 => (0x00007ffff7ffd000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7c19000)
    /lib64/ld-linux-x86-64.so.2 (0x0000555555554000)

    mt08@linux64:~/teratail.com/questions/70098$ ldd ./bof
    linux-vdso.so.1 => (0x00007ffff7ffd000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7c19000)
    /lib64/ld-linux-x86-64.so.2 (0x0000555555554000)

    mt08@linux64:~/teratail.com/questions/70098$ LD_TRACE_LOADED_OBJECTS=1 ./bof
    linux-vdso.so.1 => (0x00007ffff7ffa000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffff7a0e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ffff7dd7000)
    ```

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Cに関する質問
  • gdbで見るlibcのアドレスと、lddコマンド+nmコマンドを使って計算したlibcのアドレスが違う