Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
libtalloc — libtalloc は、GDB とともに使用して「トリビアルアロケータ」(talloc) を解析できる Python スクリプトです。 | Kitploit
ツール/GitHubGitHub/nccgroup/libtalloc
メモリフォレンジック脆弱性分析リバースエンジニアリングデバッガバイナリ解析
GitHubnccgroup/libtalloc

libtalloc

libtalloc は、GDB とともに使用して「トリビアルアロケータ」(talloc) を解析できる Python スクリプトです。

リポジトリを見る
17511年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

libtalloc

libtalloc は、GDB で使用する Python スクリプトで、"trivial allocator" (talloc) を解析するために 使用できます。talloc の入門記事はここにあります:

https://talloc.samba.org/talloc/doc/html/index.html

libtalloc は、unmask_jemalloc や libheap などのヒープ解析用の他の gdb python スクリプトに触発されて作られました。基本的な機能の一部は これらのプロジェクトと同一です。

https://github.com/cloudburst/libheap

https://github.com/argp/unmask_jemalloc

私は Python の専門家ではなく、コードの品質にはそれが反映されて いることに注意してください。気に入らない点があれば、遠慮なくパッチを送るか、 何か提案をしてください。すべてのフィードバックを歓迎します。

テスト

libtalloc は talloc のさまざまな 2.x リリースでテストされており、 バージョン間の構造上の違いに対処するために動的バージョン検出をサポート しています。32 ビットと 64 ビットでテストされていますが、網羅的 ではないため、たまに壊れても驚かないでください。

x86 と x64 である程度テストされています:

  • 2.0.7
  • 2.0.8
  • 2.1.0
  • 2.1.1

別のバージョンでテストした場合は、動作したかどうか、または何が 壊れたかを知らせてください。それに応じてスクリプトやドキュメントを更新します。

インストール

このスクリプトには、Python をサポートする比較的新しいバージョンの GDB のみが必要です。

Ubuntu 12.04 などの一部の LTS ディストリビューションでは、今でも Python 2.7 の GDB が 使用されていますが、14.04 などの新しいバージョンでは Python 3.0 を使用しています。 このスクリプトが両方で動作するように努めたので、次のようにするだけです:

root@kitploit:~
(gdb) source libtalloc.py

使用方法

機能のほとんどは unmask_jemalloc のアプローチに基づいており、 複雑なスイッチのセットではなく個別の GDB コマンドが提供されます。

talloc ライブラリの C 関数を模倣するために特別に設計された多数の メソッドが用意されており、すでにライブラリに精通している人が libtalloc を 拡張しようとする際に役立ちます。

コマンドの完全なリストを表示するには、tchelp コマンドを実行します:

root@kitploit:~
(gdb) tchelp
[libtalloc] talloc commands for gdb
[libtalloc] tcchunk -v -x <addr>  : show chunk contents (-v for verbose, -x for data dump)
[libtalloc] tcvalidate -a <addr>  : validate chunk (-a for whole heap)
[libtalloc] tcsearch <addr>       : search heap for hex value or address
[libtalloc] tcwalk <func>         : walk whole heap calling func on every chunk
[libtalloc] tcreport <addr>       : give talloc_report_full() info on memory context
[libtalloc] tcdump -s <addr>      : dump chunks linked to memory context (-s for sorted by addr)
[libtalloc] tcparents <addr>      : show all parents of chunk
[libtalloc] tcchildren <addr>     : show all children of chunk
[libtalloc] tcinfo                : show information known about heap
[libtalloc] tcprobe               : try to collect information about talloc version
[libtalloc] tchelp                : this help message

動的バージョン検出

最も重要なコマンドの 1 つは tcprobe です。実際にインストールされている talloc のバージョンを特定するために実行する必要があります。バージョンによって 構造レイアウトが大きく異なる場合があるため、ほとんどの関数を機能させるには バージョンが判明している必要があります。

コマンドが成功すると、検出されたバージョンが表示されます:

root@kitploit:~
(gdb) tcprobe
Version: 2.1.1 
File: /usr/lib/libtalloc.so.2.1.1

メタ情報

tcinfo コマンドは、tcprobe からの情報や、見つかった場合の null_context 構造体など、ヒープについて収集された情報を可能な限り 表示することを目的としています。現時点では、バージョンと null_context が設定されているかどうかのみを表示します。null_context は、 実際の階層を走査するほとんどの関数に必要であり、tchunk などの他の ほとんどの機能は、それを見つけるために自動検出を試みます。

tcprobe を実行した後、tchunk を実際に使用する前:

(gdb) tcinfo [libtalloc] null_context not yet found yet [libtalloc] Version: 2.0.7 [libtalloc] File: /usr/lib/i386-linux-gnu/libtalloc.so.2.0.7

次に、次のようにチャンクを解析した後:

(gdb) tcchunk 0xb94a52b0 WARNING: 0xb94a52b0 not a talloc_chunk. Assuming ptr to chunk data 0xb94a5280 sz:0x0000003c, flags:...., name:struct tevent_context

tcinfo を使用して、後からそれが見つかったことを確認できます。

(gdb) tcinfo [libtalloc] null_context: 0xb94a5028 [libtalloc] Version: 2.0.7 [libtalloc] File: /usr/lib/i386-linux-gnu/libtalloc.so.2.0.7

null_context が設定されたので、通常は設定されていないと警告される tcsearch コマンドなどの他のコマンドを実行できるようになりました。

チャンク解析

tcchunk は、チャンクの要約、各フィールドのより詳細な出力、または 周囲のすべてのチャンクに関する非常に詳細な情報を提供します。

注: tcchunk について覚えておくべき重要な点の 1 つは、内部的に tc_chunk() メソッドを 使用していることです。このメソッドは、チャンクアドレスを渡す際に発生する 誤りを修正しようとします。具体的には、チャンクデータ自体のアドレスを渡した場合、 期待される talloc マジックが見つからないと、メモリ内の少し手前で正当な チャンクヘッダーを探します。破損したシナリオではこれに惑わされる可能性が あるため、大まかな解析を行う場合を除き、常に明示的なアドレスを 渡すようにしてください。

要約出力:

root@kitploit:~
(gdb) tcchunk 0x80a13c88
0x80a13c88 sz:0x00000020, flags:..p., name:struct netr_ServerPasswordSet

以下は、要約出力内のチャンクの凡例です:

root@kitploit:~
p - Member of a pool (POOLMEM flag)
P - Chunk is a pool (POOL flag)
F - Chunk is free (FREE flag)
L - Chunk is looped (LOOP flag)

詳細出力:

root@kitploit:~
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x0
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248

検証

talloc チャンクには、それらが正常かどうかを検証するために使用できる マジック値がいくつか含まれています。tcvalidate コマンドはチャンクを解析して、 チャンクマジックが期待どおりであることを確認します。さらに、他のすべての ポインタメンバーを解析して、それらが実際に(gdb が認識する)メモリ範囲内に あるかどうか、サイズが有効かどうかなどを確認します。

root@kitploit:~
(gdb) tcvalidate 0x80a13c88
Chunk header is valid

組み込みメソッドを使用して値を変更し、どのように失敗するかを示します:

root@kitploit:~
(gdb) python set_destructor(tc_chunk(0x80a13c88), 0x41414141)
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x41414141
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248
(gdb) tcvalidate 0x80a13c88
Chunk header is invalid:
0x80a13c88: Chunk has bad destructor pointer 0x41414141

親の検索

tcparents を使用すると、指定されたチャンクのすべての親を表示できます:

root@kitploit:~
(gdb) tcparents 0x80a13c88
0x809f8300: null_context
  0x80a08660: TALLOC_CTX *
    0x809f8370: talloc_new: ../lib/util/talloc_stack.c:147
      0x809fb680: talloc_new: ../lib/util/talloc_stack.c:147
        0x80a13258: UNNAMED
          0x80a13c58: talloc_new: ../lib/util/talloc_stack.c:147
            0x80a13c88: struct netr_ServerPasswordSet

子の検索

tchildren を使用すると、指定されたチャンクのすべての子(孫など)を 表示できます:

root@kitploit:~
(gdb) tcchildren 0x80a13c88
0x80a14088: struct netr_Authenticator
0x80a14048: librpc/gen_ndr/ndr_netlogon.c:10964
0x80a14008: librpc/gen_ndr/ndr_netlogon.c:10958
0x80a13fc8: librpc/gen_ndr/ndr_netlogon.c:10951
0x80a13f88: lib/charcnv.c:506
0x80a13ec8: lib/charcnv.c:506
0x80a13d48: librpc/gen_ndr/ndr_netlogon.c:10913
  0x80a13e08: 
0x80a13cd8: struct ndr_pull
  0x80a13f48: struct ndr_token_list
  0x80a13f08: struct ndr_token_list
  0x80a13e88: struct ndr_token_list
  0x80a13e48: struct ndr_token_list
  0x80a13dc8: struct ndr_token_list
  0x80a13d88: struct ndr_token_list

プール解析

talloc にはプールチャンクの概念があります。これらは基本的に通常の talloc チャンクですが、システムの基盤となる malloc() 実装にフォールバックするのではなく、 新しいチャンクの割り当てに使用されます。プールチャンクのヘッダーは使用される バージョンによって少し異なり、パディングを使用する場合もあれば、 プレフィックス/サフィックスヘッダーを使用する場合もあります。

tcpool を使用すると、tcchunk と同様にプールチャンクヘッダーを解析できます:

root@kitploit:~
# First we find a pool to analyze
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x0
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248

(gdb) tcpool -v 0x80a13248
struct talloc_pool_hdr @ 0x80a13248 {
end          = 0x80a14108
object_count = 0x19
poolsize     = 0x2000
struct talloc_chunk @ 0x80a13258 {
next         = 0x0
prev         = 0x0
parent       = 0x809fb680
child        = 0x80a13c58
refs         = 0x0
destructor   = 0x80429aa0
name         = 0x0 (UNNAMED)
size         = 0x0
flags        = 0xe8150c74 (POOL)
limit        = 0x0
pool         = 0x0

上記のケースでは、プールにはプレフィックス付きの talloc_pool_hdr があり、 それが表示されています。tcpool に -l オプションを渡すと、プール内の割り当て済み チャンクをすべて一覧表示できます:

root@kitploit:~
(gdb) tcpool -l 0x80a13248
Pool summary -- objects: 0x19, total size: 0x2000, space left: 0x1180, next free: 0x80a14108
0x80a13258 sz:0x00000000, flags:.P.., name:UNNAMED
0x80a13288 sz:0x000007a3, flags:..p., name:char
0x80a13a68 sz:0x0000005c, flags:..p., name:struct smb_request
0x80a13af8 sz:0x00000008, flags:..p., name:struct pipe_write_andx_state
0x80a13b38 sz:0x00000038, flags:..p., name:struct tevent_req
0x80a13ba8 sz:0x00000028, flags:..p., name:struct tevent_immediate
0x80a13c08 sz:0x00000014, flags:..p., name:struct np_write_state
0x80a13c58 sz:0x00000000, flags:..p., name:talloc_new: ../lib/util/talloc_stack.c:147
0x80a13c88 sz:0x00000020, flags:..p., name:struct netr_ServerPasswordSet
0x80a13cd8 sz:0x00000038, flags:..p., name:struct ndr_pull
0x80a13d48 sz:0x00000001, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10913
0x80a13d88 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13dc8 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13e08 sz:0x00000001, flags:..p., name:
0x80a13e48 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13e88 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13ec8 sz:0x00000008, flags:..p., name:lib/charcnv.c:506
0x80a13f08 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13f48 sz:0x00000010, flags:..p., name:struct ndr_token_list
0x80a13f88 sz:0x00000008, flags:..p., name:lib/charcnv.c:506
0x80a13fc8 sz:0x0000000c, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10951
0x80a14008 sz:0x00000010, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10958
0x80a14048 sz:0x0000000c, flags:..p., name:librpc/gen_ndr/ndr_netlogon.c:10964
0x80a14088 sz:0x0000000c, flags:..p., name:struct netr_Authenticator
0x80a140c8 sz:0x0000000b, flags:..p., name:/etc/samba

上記の出力の P フラグに注意してください。最上位のチャンクが、その下の すべてのチャンクを保持するプールチャンクです。

ヒープダンプ

tcdump を使用すると、ツリー全体のすべてのチャンクをダンプできます。 デフォルトでは階層順に表示されますが、-s オプションを使用すると出力を アドレス順に並べ替えることができます。

root@kitploit:~
(gdb) tcdump -a 0x809f8300
0x809f8300 sz:0x00000000, flags:...., name:null_context
0x80a0b3f8 sz:0x0000000c, flags:...., name:struct handle_list
0x809ff178 sz:0x00000014, flags:...., name:struct security_token
0x80a089e8 sz:0x00000198, flags:...., name:lib/util_nttoken.c:50
0x80a07268 sz:0x00000188, flags:...., name:connection_struct
0x80a08bc8 sz:0x00000020, flags:...., name:struct fd_handle
0x80a00c30 sz:0x000000f0, flags:...., name:struct files_struct
0x80a083b8 sz:0x00000008, flags:...., name:struct fake_file_handle
0x80a08c20 sz:0x0000009c, flags:...., name:struct pipes_struct
0x80a07900 sz:0x00000760, flags:...., name:uint8_t
0x80a07428 sz:0x000000c0, flags:...., name:struct auth_serversupplied_info
0x80a06390 sz:0x00000001, flags:...., name:
0x80a06350 sz:0x00000007, flags:...., name:nobody
0x80a06158 sz:0x000000cc, flags:...., name:struct netr_SamInfo3
0x80a062d8 sz:0x00000044, flags:...., name:struct dom_sid
[SNIP]

tcreport は tcdump に似たコマンドですが、出力をある程度整形し、 talloc ライブラリ自体が提供する talloc_report_full() デバッグ関数を 模倣することを目的としています。

root@kitploit:~
(gdb) tcreport 0x80a0b3f8 -a
Full talloc report on 'null_context' (total 558651 bytes in 446 blocks)
    struct handle_list             contains     12 bytes in   1 blocks (ref 67) 0x80a0b3f8
    struct security_token          contains    428 bytes in   2 blocks (ref 66) 0x809ff178
        lib/util_nttoken.c:50          contains    408 bytes in   1 blocks (ref 0) 0x80a089e8
    connection_struct              contains 531071 bytes in  36 blocks (ref 65) 0x80a07268
        struct fd_handle               contains     32 bytes in   1 blocks (ref 4) 0x80a08bc8
        struct files_struct            contains 529681 bytes in  22 blocks (ref 3) 0x80a00c30
            struct fake_file_handle        contains 529308 bytes in  19 blocks (ref 1) 0x80a083b8
                struct pipes_struct            contains 529300 bytes in  18 blocks (ref 0) 0x80a08c20
                    uint8_t                        contains   1888 bytes in   1 blocks (ref 2) 0x80a07900
                    struct auth_serversupplied_info contains    934 bytes in  10 blocks (ref 1) 0x80a07428
                                                       contains      1 bytes in   1 blocks (ref 4) 0x80a06390
                        nobody                         contains      7 bytes in   1 blocks (ref 3) 0x80a06350
                        struct netr_SamInfo3           contains    290 bytes in   4 blocks (ref 2) 0x80a06158
[SNIP]

検索

検索用のコマンドは 2 つあります:tcsearch と tcfindaddr です。

tcsearch を使用すると、指定された 16 進値を含むチャンクを検索できます。 これは、(既知の場合は)null_context から、または指定された開始チャンクから ツリー全体の階層を走査して機能します。

root@kitploit:~
(gdb) python set_destructor(tc_chunk(0x80a13c88), 0x41414141)
(gdb) tcsearch 0x41414141 0x809f8300
[libtalloc] 0x41414141 found in chunk at 0x80a1d218
[libtalloc] 0x41414141 found in chunk at 0x80a13c88
(gdb) tcchunk -v 0x80a1d218
struct talloc_chunk @ 0x80a1d218 {
next         = 0x80a00158
prev         = 0x809fb0c8
parent       = 0x0
child        = 0x0
refs         = 0x0
destructor   = 0x0
name         = 0x8071fcbd (uint8_t)
size         = 0x80050
flags        = 0xe8150c70 ()
limit        = 0x0
pool         = 0x0
(gdb) tcchunk -x 0x80a1d218
0x80a1d218 sz:0x00080050, flags:...., name:uint8_t
Chunk data (524368 bytes):
0x80a1d248:	0x41414141	0x00000000	0x00000000	0x00000000
0x80a1d258:	0x00000001	0x00000000	0x00000001	0x00020000
0x80a1d268:	0x00000001	0x00000000	0x00000001	0xaaaa0000
[SNIP]    
(gdb) tcchunk -v 0x80a13c88
struct talloc_chunk @ 0x80a13c88 {
next         = 0x0
prev         = 0x80a140c8
parent       = 0x0
child        = 0x80a14088
refs         = 0x0
destructor   = 0x41414141
name         = 0x807d9f2f (struct netr_ServerPasswordSet)
size         = 0x20
flags        = 0xe8150c78 (POOLMEM)
limit        = 0x0
pool         = 0x80a13248

tcfindaddr を使用すると、アドレスが talloc ツリー内のチャンクの境界内に 収まるかどうかを判断できます。たとえば、0x80a1d3280 に制御可能なデータが あることがわかっている場合、それがチャンク内に収まるかどうかを確認したいと します。2 番目のアドレスは null_context ですが、ヒープの先頭を見つけられる任意のチャンクにすることができます。

root@kitploit:~
(gdb) tcfindaddr 0x80a1d328 0x809f8300
[libtalloc] address 0x80a1d328 falls within chunk @ 0x80a1d218 (size 0x80050)

ヒープ走査

ツリー検索の一部は、tcwalk コマンドを介して公開した再帰関数を使用して 行われます。これは、ツリー内で見つかったすべてのチャンクに対して呼び出される Python メソッドを指定できるヘルパー関数です。

以下の例では、ヒープ内のすべてのチャンクに対してヒープ検証メソッドを 呼び出して、破損がないか確認します。

root@kitploit:~
(gdb) tcwalk validate_chunk 
0x80a13c88: Chunk has bad destructor pointer 0x41414141

null_context が設定されていない場合は、2 番目の引数としてチャンクアドレスを 渡す必要があることに注意してください。

連絡先

著者: Aaron Adams

メール: aaron (dot) adams (at) nccgroup (dot) trust

Twitter: @fidgetingbits

ツールをダウンロード