Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
libtalloc — libtalloc is a python script for use with GDB that can be used to analyse the "trivial allocator" (talloc) | Kitploit
Инструменты/GitHubGitHub/nccgroup/libtalloc
Memory ForensicsVulnerability AnalysisReverse EngineeringDebuggersBinary Analysis
GitHubnccgroup/libtalloc

libtalloc

libtalloc is a python script for use with GDB that can be used to analyse the "trivial allocator" (talloc)

Репозиторий
17511 лет назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

libtalloc

libtalloc — это python-скрипт для использования с GDB, который можно применять для анализа «тривиального аллокатора» (talloc). Введение в talloc можно найти здесь:

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

libtalloc был вдохновлён другими gdb python-скриптами для анализа куч, такими как unmask_jemalloc и libheap. Некоторая базовая функциональность идентична этим проектам.

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

Если вы протестируете его на другой версии, пожалуйста, сообщите мне, сработал ли он, или что сломалось, и я постараюсь обновить его и/или документацию соответствующим образом.

Установка

Скрипту требуется относительно современная версия GDB с поддержкой python.

Некоторые LTS-дистрибутивы, например Ubuntu 12.04, всё ещё используют GDB с python 2.7, тогда как более новые версии, такие как 14.04, используют python 3.0. Я постарался сделать так, чтобы этот скрипт работал с обоими, так что вам нужно только:

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

Использование

Большая часть функциональности смоделирована по подходу unmask_jemalloc, где предоставляется отдельная команда GDB, а не сложный набор переключателей.

Доступен ряд методов, специально разработанных для имитации C-функций библиотеки talloc, чтобы помочь людям, пытающимся расширить 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

Динамическое определение версии

Одна из самых важных команд — 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 требуется для большинства функций, которые обходят фактическую иерархию, и чтобы найти его, большинство других функций, таких как tcchunk и т.п., попытаются автоматически найти его.

После запуска tcprobe, но до фактического использования tcchunk:

(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 использует метод tc_chunk(), который пытается исправить ошибки, допущенные при передаче адреса чанка. В частности, если вы передаёте адрес самих данных чанка, и он не находит ожидаемого магического значения talloc, он будет искать легитимный заголовок чанка чуть раньше в памяти. Это может помешать вам в сценариях с повреждёнными данными, поэтому всегда убедитесь, что вы передаёте явный адрес, если только вы не проводите поверхностный анализ.

Сводный вывод:

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

Ниже приведена легенда для чанков в сводном выводе:

root@kitploit:~
p - Член пула (флаг POOLMEM)
P - Чанк является пулом (флаг POOL)
F - Чанк свободен (флаг FREE)
L - Чанк зациклен (флаг LOOP)

Подробный вывод:

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

Поиск детей

tcchildren можно использовать для просмотра всех детей (и внуков и т.д.) указанного чанка:

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 есть концепция пулов (pool chunks). По сути, это обычные чанки 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, который и показан. Опцию -l можно передать tcpool, чтобы перечислить все выделенные чанки внутри пула:

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_report_full(), предоставляемой самой библиотекой talloc.

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]

Поиск

Существуют две команды для поиска: tcsearch и tcfindaddr.

tcsearch можно использовать для поиска чанков, содержащих заданное шестнадцатеричное значение. Он работает, обходя всю иерархию дерева, начиная с 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 есть данные, которыми вы управляете, и вы хотите проверить, попадают ли они в чанк. Обратите внимание, что второй адрес — это 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 не был установлен, вам нужно передать адрес чанка вторым аргументом.

Контакты

Автор: Aaron Adams

Email: aaron (dot) adams (at) nccgroup (dot) trust

Twitter: @fidgetingbits

Скачать инструмент