Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
libtalloc — libtalloc é um script Python para uso com GDB que pode ser utilizado para analisar o "trivial allocator" (talloc) | Kitploit
Ferramentas/GitHubGitHub/nccgroup/libtalloc
Forensia de MemóriaAnálise de VulnerabilidadesEngenharia ReversaDepuradoresAnálise de Binários
GitHubnccgroup/libtalloc

libtalloc

libtalloc é um script Python para uso com GDB que pode ser utilizado para analisar o "trivial allocator" (talloc)

Ver Repositório
1755há 11 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

libtalloc

O libtalloc é um script python para uso com GDB que pode ser usado para analisar o "alocador trivial" (talloc). Uma introdução sobre o talloc pode ser encontrada aqui:

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

O libtalloc foi inspirado por outros scripts python para gdb de análise de heaps, como unmask_jemalloc e libheap. Algumas funcionalidades básicas são idênticas às desses projetos.

https://github.com/cloudburst/libheap

https://github.com/argp/unmask_jemalloc

Por favor, note que não sou um guru de python e a qualidade do código reflete isso. Se você vir algo que o desagrada, sinta-se à vontade para enviar um patch ou dar algumas sugestões. Todo feedback é bem-vindo.

Testes

O libtalloc foi testado em várias versões 2.x do talloc e suporta detecção dinâmica de versão para tentar contornar as diversas diferenças estruturais entre as versões. Foi testado em 32 bits e 64 bits, porém não de forma exaustiva, então não se surpreenda se quebrar de vez em quando.

Foi testado até certo ponto em x86 e x64:

  • 2.0.7
  • 2.0.8
  • 2.1.0
  • 2.1.1

Se você testá-lo em outra versão, por favor me avise se funcionou ou o que quebrou, e tentarei atualizá-lo e/ou a documentação de acordo.

Instalação

O script apenas requer uma versão relativamente moderna do GDB com suporte a python.

Algumas distros LTS, como Ubuntu 12.04, ainda usam GDB com python 2.7, enquanto versões mais novas, como 14.04, usam python 3.0. Tentei fazer este script funcionar com ambos, então você só deve precisar de:

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

Uso

A maior parte da funcionalidade é modelada a partir da abordagem do unmask_jemalloc, onde um comando GDB separado é fornecido em vez de um conjunto complexo de opções.

Vários métodos projetados especificamente para imitar as funções C da biblioteca talloc estão disponíveis, para ajudar pessoas que tentam estender o libtalloc se já estiverem familiarizadas com a biblioteca.

Para ver uma lista completa de comandos, você pode executar o comando 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

Sondagem Dinâmica de Versão

Um dos comandos mais importantes é o tcprobe. Ele precisa ser executado para descobrir qual versão do talloc está realmente instalada. Os layouts de estrutura para diferentes versões podem variar significativamente, portanto, para que a maioria das funções funcione, a versão precisa ser conhecida.

Se o comando funcionar, ele deve informar a versão detectada:

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

Meta-informação

O comando tcinfo tem como objetivo mostrar o máximo de informações coletadas sobre o heap possível, como as informações do tcprobe, a estrutura null_context se ela foi encontrada, e mais. No momento, ele mostra apenas a versão e se o null_context está definido. O null_context é necessário para a maioria das funções que percorrem a hierarquia real e, para encontrá-lo, a maioria das outras funcionalidades, como tchunk, etc., tentará localizá-lo automaticamente.

Depois que o tcprobe é executado, mas antes que o tchunk seja realmente usado:

root@kitploit:~
(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

Então, depois de analisar um chunk, assim:

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

Você pode confirmar que ele foi encontrado depois usando o tcinfo.

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

Agora que o null_context está definido, você pode executar outros comandos que normalmente reclamariam que ele não estava definido, como o comando tcsearch.

Análise de chunk

O tcchunk pode fornecer um resumo do chunk, uma saída mais detalhada de cada campo ou informações extremamente detalhadas sobre cada chunk ao redor.

NOTA: Uma coisa importante a observar sobre o tcchunk é que, internamente, ele usa o método tc_chunk(), que tenta corrigir erros cometidos ao informar o endereço do chunk. Especificamente, se você passar o endereço dos dados do chunk em si, e ele não encontrar a magic esperada do talloc, ele procurará um cabeçalho de chunk legítimo um pouco antes na memória. Isso pode atrapalhar em cenários de corrupção, então certifique-se sempre de estar passando o endereço explícito, a menos que esteja fazendo uma análise superficial.

Saída resumida:

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

A seguir está uma legenda para os chunks na saída resumida:

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)

Saída detalhada:

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

Validação

Os chunks do talloc contêm alguns valores mágicos que podem ser usados para validar se são íntegros. O comando tcvalidate analisa um chunk para garantir que a magic do chunk seja a esperada. Além disso, ele analisa todos os outros membros ponteiro para garantir que realmente caiam em faixas de memória (conhecidas pelo gdb), se o tamanho é válido, etc.

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

Usaremos um método embutido para modificar um valor e mostrar como isso poderia falhar:

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

Encontrando pais

O tcparents pode ser usado para ver todos os pais do chunk fornecido:

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

Encontrando filhos

O tchildren pode ser usado para ver todos os filhos (e netos, etc.) do chunk fornecido:

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

Análise de pool

O talloc tem o conceito de chunks de pool. Eles são basicamente chunks normais do talloc, mas são usados para alocar novos chunks em vez de depender da implementação malloc() subjacente do sistema. Um chunk de pool tem cabeçalhos ligeiramente diferentes dependendo da versão usada, às vezes usando padding e às vezes usando um cabeçalho de prefixo/sufixo.

O tcpool pode ser usado para analisar o cabeçalho de um chunk de pool, semelhante ao 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

No caso acima, o pool tinha um talloc_pool_hdr prefixado, que é mostrado. A opção -l pode ser passada para o tcpool para listar todos os chunks alocados dentro de um pool:

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

Observe a flag P na saída acima, sendo o chunk do topo o chunk de pool que contém todos os chunks abaixo.

Despejo do heap

O tcdump pode ser usado para despejar todos os chunks da árvore inteira. Por padrão, eles são mostrados em ordem hierárquica, porém a opção -s pode ser usada para ordenar a saída por endereço.

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]

O tcreport é um comando semelhante ao tcdump, mas embeleza um pouco a saída e tem como objetivo imitar a função de depuração talloc_report_full() fornecida pela própria biblioteca 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]

Pesquisa

Existem dois comandos para pesquisa: tcsearch e tcfindaddr.

O tcsearch pode ser usado para encontrar chunks que contenham o valor hexadecimal fornecido. Ele funciona percorrendo toda a hierarquia da árvore a partir do null_context (se conhecido) ou de um chunk inicial fornecido.

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

O tcfindaddr pode ser usado para determinar se um endereço está dentro do limite de um chunk na árvore do talloc. Digamos que você saiba que 0x80a1d3280 tem alguns dados que você controla, então você quer ver se ele está dentro de um chunk. Observe que o segundo endereço é o null_context, mas pode ser qualquer chunk que nos permita encontrar o topo do heap.

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

Percorrendo o heap

Parte da busca na árvore é feita usando uma função recursiva que expus através do comando tcwalk. É uma função auxiliar que permite especificar um método python que será chamado em cada chunk encontrado na árvore.

No exemplo abaixo, chamaremos o método de validação do heap em cada chunk do heap para ver se algo está corrompido.

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

Observe que, se o null_context não tiver sido definido, você precisa passar um endereço de chunk como segundo argumento.

Contato

Escrito por Aaron Adams

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

Twitter: @fidgetingbits

Baixar ferramenta