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
LogFileParser — Analisador para $LogFile em NTFS | Kitploit
Ferramentas/GitHubGitHub/jschicht/logfileparser
Forensia de DiscoAnálise ForenseRecuperação de DadosForensia DigitalAnálise de BináriosAnálise de Logs
GitHubjschicht/logfileparser

LogFileParser

Analisador para $LogFile em NTFS

Ver Repositório
218299há 3 mesesRevisado pelo Kitploit

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

Recursos Decodifica e extrai registros $LogFile e entradas de transação. Decodifica alterações de atributos NTFS. Opcionalmente resolve toda a informação da lista de dataruns disponível no $LogFile. Opção: "Reconstruct data runs". Recupera transações do espaço slack dentro do $LogFile. Escolha reconstruir cabeçalhos ausentes ou danificados de transações encontradas no slack. Opção: "Rebuild header". Opcionalmente também afina o resultado com um valor de nível de erro LSN. Opção: "LSN error level". Registra em csv e importa para base de dados sqlite com várias tabelas. Opcionalmente importa a saída csv do mft2csv para a base de dados. Escolha entre 6 formatos de timestamp diferentes. Escolha a precisão do timestamp: None, MilliSec e NanoSec. Escolha o separador de precisão em milissegundos. Escolha o separador de precisão em nanossegundos. Escolha o ajuste de região para timestamps. O padrão é apresentar timestamps em UTC 0.0. Escolha o separador de saída. Opção: "Set separator". Saída UNICODE ou ANSI configurável. Opção "Unicode". Tamanho de registro MFT configurável (1024 ou 4096). Opção "MFT record size". Opcionalmente decodifica transações individuais ou transações parciais (fragmento). Opção para reconstruir RCRD's a partir de transações únicas ou múltiplas (fragmentos). Opção para configurar $LogFile corrompido. Útil com RCRD's carved como entrada. Opção para ignorar fixups (para $LogFile corrompido, tipicamente carved da memória). Saída verbosa detalhada em debug.log. Lista configurável separada por vírgulas de lsn's para acionar informação ultra verbosa sobre transações específicas em debug.log. Configuração para SO de 32 bits. Configuração para extração de dados binários de atualizações de dados residentes. sql autogerado para importar a saída para base de dados MySql. Opção para ignorar todo o processamento sqlite3 para acelerar o parsing total. Modo de linha de comandos opcional. Suporta errorlevel adequado para scripting em lote.

Contexto O NTFS foi concebido como um sistema de ficheiros recuperável. Isto é feito através do registo de todas as transações que alteram a estrutura do volume. Assim, qualquer alteração a um ficheiro no volume exigirá que algo seja também registado no $LogFile, para que possa ser revertido em caso de falha do sistema em qualquer momento. Portanto, muita informação é escrita neste ficheiro, e como é circular, significa que novas transações estão a sobrescrever registos mais antigos no ficheiro. Assim, é algo limitado quanto de dados históricos podem ser recuperados deste ficheiro. Novamente, isso dependeria do tipo de volume e do tamanho do $LogFile. No systemdrive de um sistema frequentemente utilizado, provavelmente obterá apenas algumas horas de histórico, enquanto um disco externo/secundário com ficheiros de backup provavelmente conterá mais informação histórica. E um ficheiro de 2MB conterá muito menos histórico do que um de 256MB. Então, em que intervalo de tamanho pode este ficheiro ser configurado? Qualquer coisa a partir de 256 KB. Configurar o tamanho para 2 GB pode ser feito assim, "chkdsk D: /L:2097152". Como um logfile de grande dimensão impacta o desempenho está fora do âmbito deste texto. Definir abaixo de 2048 normalmente não é possível. No entanto, é possível através de patching da untfs.dll: http://code.google.com/p/mft2csv/wiki/Tiny_NTFS

Introdução Este parser irá decodificar e extrair muita informação de transação do $LogFile em NTFS. São gerados vários csv's, bem como uma base de dados sqlite chamada ntfs.db contendo toda a informação relevante. A saída é extremamente detalhada e de muito baixo nível, o que significa que requer algum conhecimento decente de NTFS para a compreender. Os tipos de transação Redo atualmente tratados com decodificação de saída significativa são:

InitializeFileRecordSegment CreateAttribute DeleteAttribute UpdateResidentValue UpdateNonResidentValue UpdateMappingPairs SetNewAttributeSizes AddindexEntryRoot DeleteindexEntryRoot AddIndexEntryAllocation DeleteIndexEntryAllocation WriteEndOfIndexBuffer SetIndexEntryVcnRoot SetIndexEntryVcnAllocation UpdateFileNameRoot UpdateFileNameAllocation SetBitsInNonresidentBitMap ClearBitsInNonresidentBitMap OpenNonresidentAttribute OpenAttributeTableDump AttributeNamesDump DirtyPageTableDump TransactionTableDump UpdateRecordDataRoot UpdateRecordDataAllocation CompensationlogRecord

A lista de atributos atualmente suportados: $STANDARD_INFORMATION $ATTRIBUTE_LIST $FILE_NAME $OBJECT_ID $SECURITY_DESCRIPTOR $VOLUME_NAME $VOLUME_INFORMATION $DATA $INDEX_ROOT $INDEX_ALLOCATION $REPARSE_POINT $EA_INFORMATION $EA $LOGGED_UTILITY_STREAM

Portanto, basicamente todos os atributos são suportados.

Explicação das diferentes saídas geradas:

LogFile.csv: O csv principal gerado pelo parser.

LogFile_DataRuns.csv A informação de entrada necessária para reconstruir dataruns

LogFile_DataRunsResolved.csv A saída final dos dataruns reconstruídos

LogFile_INDX_I30.csv Todos os registos de índice extraídos e decodificados (IndexRoot/IndexAllocation)

LogFileJoined.csv O mesmo que LogFile.csv, mas com informação de nome de ficheiro associada a partir do $UsnJrnl ou csv do mft2csv.

MFTRecords.bin $MFT fictício recriado com base nos registos MFT encontrados em transações InitializeFileRecordSegment. Pode usar mft2csv neste (lembre-se de configurar "broken MFT" e "Fixups" corretamente).

LogFile_lfUsnJrnl.csv Registos para o $UsnJrnl que foram decodificados dentro do $LogFile

LogFile_UndoWipe_INDX_I30.csv Todas as operações de undo para limpeza de índices de diretório (INDX).

LogFile_AllTransactionHeaders.csv Todos os cabeçalhos das transações decodificadas.

LogFile_BitsInNonresidentBitMap.csv Todas as operações SetBitsInNonresidentBitMap decodificadas.

LogFile_DirtyPageTable32bit.csv e LogFile_DirtyPageTable64bit.csv Todas as entradas em cada operação DirtyPageTableDump decodificada, tanto para SO de 32 bits como de 64 bits.

LogFile_Mft_ObjectId_Entries.csv Atributos $ObjectId decodificados.

LogFile_ObjIdO.csv Todas as decodificações do ficheiro de sistema $ObjId:$O.

LogFile_OpenAttributeTable.csv Todas as entradas em cada operação OpenAttributeTableDump decodificada.

LogFile_QuotaO.csv Todas as decodificações do ficheiro de sistema $Quota:$O.

LogFile_QuotaQ.csv Todas as decodificações do ficheiro de sistema $Quota:$Q.

LogFile_RCRD.csv Todos os cabeçalhos dos registos RCRD decodificados.

LogFile_ReparseR.csv Todas as decodificações do ficheiro de sistema $Reparse:$R.

LogFile_SecureSDH.csv Todas as decodificações do ficheiro de sistema $Secure:$SDH.

LogFile_SecureSII.csv Todas as decodificações do ficheiro de sistema $Secure:$SII.

LogFile_SecurityDescriptors.csv Security descriptors decodificados. A origem pode ser de $SECURITY_DESCRIPTOR ou $Secure:$SDS.

LogFile_SlackAttributeNamesDump.csv Todas as entradas de transações AttributeNamesDump decodificadas encontradas no espaço slack.

LogFile_SlackOpenAttributeTable.csv Todas as entradas de transações OpenAttributeTableDump decodificadas encontradas no espaço slack.

LogFile_TransactionTable.csv Transações TransactionTableDump decodificadas.

LogFile_Filenames.csv Todos os nomes de ficheiro resolvidos com MftRef, MftRefSeqNo e Lsn.

LogFile_TxfData.csv Dados decodificados de $DATA:$TXF_DATA em $LOGGED_UTILITY_STREAM.

LogFile_UpdateFileName_I30.csv Todas as decodificações de UpdateFileNameRoot e UpdateFileNameAllocation para operações redo e undo.

LogFile_CompensationlogRecord.csv Todas as decodificações de CompensationlogRecord. Não relevante para nt5.x.

Ntfs.db Um ficheiro de base de dados sqlite com tabelas quase equivalentes aos csv's acima. A base de dados contém 5 tabelas: DataRuns IndexEntries LogFile LogFileTmp (tabela temporária usada ao recriar dataruns). UsnJrnl

Timestamps Os padrões são apresentados em UTC 0.00, e com precisão de nanossegundos. O formato padrão é YYYY-MM-DD HH:MM:SS:MSMSMS:NSNSNSNS. Estes podem ser configurados. Os diferentes timestamps referem-se a: CTime significa File Create Time. ATime significa File Modified Time. MTime significa MFT Entry modified Time. RTime significa File Last Access Time.

Reconstruir dataruns.

Muitas operações no sistema de ficheiros irão acionar uma transação no $LogFile. As relacionadas com o atributo $DATA, ou seja, o conteúdo de um ficheiro, são até agora identificadas como;

InitializeFileRecordSegment CreateAttribute UpdateMappingPairs SetNewAttributeSizes

Todas elas deixam informação diferente no $LogFile. As modificações de dados residentes comportam-se de forma diferente e não podem ser reconstruídas assim simplesmente, pelo menos em volumes NTFS originários de versões modernas do Windows.

InitializeFileRecordSegment é quando um novo ficheiro é criado. Assim, terá o atributo $FILE_NAME, bem como o conteúdo original do atributo $DATA, incluindo dataruns. Como o $LogFile é circular, e eventos mais antigos são sobrescritos por mais recentes, o desafio com o $LogFile é obter informação suficientemente atrás no tempo. No entanto, se InitializeFileRecordSegment estiver presente, então deveríamos conseguir reconstruir tudo, uma vez que todos os registos escritos depois disso também estarão disponíveis. Teremos também informação sobre o offset para a lista de dataruns. Este é um offset relativo calculado a partir do início do atributo $DATA. Esta é uma informação importante para ter ao calcular onde na lista de dataruns o UpdateMappingPairs fez a sua modificação.

CreateAttribute é o atributo original quando foi criado pela primeira vez (se não for escrito como parte de InitializeFileRecordSegment). Com este também deveríamos conseguir reconstruir dataruns, uma vez que temos todas as transações disponíveis. No entanto, este por si só não nos fornecerá o nome do ficheiro. Aqui também temos o offset para a lista de dataruns disponível, o que é extremamente útil ao resolver UpdateMappingPairs.

UpdateMappingPairs é uma transação quando são realizadas modificações ao $DATA/dataruns (o conteúdo do ficheiro mudou). A informação encontrada nesta transação não é completa, e contém apenas os novos valores adicionados à lista de dataruns existente. Contém também um offset relativo que nos diz onde na lista de dataruns as alterações foram escritas. Este offset é usado em combinação com o offset para datarun conforme encontrado em InitializeFileRecordSegment e CreateAttribute.

SetNewAttributeSizes é uma transação que contém informação sobre quaisquer modificações relacionadas com valores de tamanho feitas ao atributo $DATA. Está intimamente ligada ao UpdateMappingPairs que contém apenas alterações de dataruns.

Com as 4 operações redo acima, pode, para um determinado número de referência (ficheiro distinto), reconstruir parte do histórico de alterações do sistema de ficheiros do ficheiro. Devido à sua circularidade, temos apenas parte do histórico, o mais recente. A extensão do histórico que podemos recuperar depende muito do tipo de volume que é o alvo. Se for um volume de sistema, então uma semana de histórico é provavelmente mais do que se poderia esperar, enquanto um disco removível ou externo ou secundário conterá muito mais histórico. Assim, podemos reconstruir o histórico completo de um ficheiro eliminado (tendo o seu registo $MFT sobrescrito), e por sua vez recriar a lista de dataruns para realizar recuperação sobre ela. Noutros casos podemos não conseguir reconstruir o histórico completo, pelo que apenas uma lista parcial de dataruns pode ser reconstruída. O ficheiro csv final com os dataruns ajustados, LogFile_DatarunsModified.csv, terá os dataruns apresentados de forma diferente.

Explicação: Os que começam com "!" indicam que a lista completa de dataruns foi recriada. Os que começam com "?" indicam uma recuperação parcial, com o número de "**" a representar os bytes em falta da lista original de dataruns.

Para simplificar a recuperação de um ficheiro com base num datarun, pode usar-se o PoC anexado chamado ExtractFromDataRuns. É bastante autoexplicativo. Basta preencher a lista completa de dataruns, o tamanho real e o tamanho inicial, e um nome para o ficheiro de saída. Opcionalmente escolha processar ficheiros de imagem (disco ou partição). Assinale também se foi detetado algum flag de compressão/sparse. Alimentá-lo com uma lista de dataruns parcialmente reconstruída não funcionará! Note-se que alternate data streams podem ser distinguidos pela presença de um dataname e também por valores OffsetInMft diferentes para um dado fileref.

O pacote de download separado "SampleTinyNtfsVolume.zip" tem uma imagem de partição com um pequeno volume NTFS para testar. No volume existem 2 ficheiros não residentes eliminados, ambos com o seu registo MFT sobrescrito por novos ficheiros. Qualquer software de recuperação decente baseado em pesquisa de assinatura deverá conseguir recuperar o ficheiro jpg (Tulips.jpg), porque é contíguo. No entanto, muito provavelmente não identificarão o seu nome de ficheiro, nem qualquer outra informação sobre o ficheiro. O segundo ficheiro provavelmente não será recuperável usando ferramentas padrão, porque está fragmentado (comprimido), e ao ter o seu registo MFT sobrescrito, resolver o ficheiro sem a lista de dataruns é impossível. Usando o PoC podemos identificar o nome do ficheiro (suspicious.zip) e extraí-lo em perfeitas condições (não se preocupe, contém apenas uma das imagens de exemplo fornecidas com o Windows). Leia o ficheiro readme.DataRunsResolved.txt para os detalhes sobre a imagem de exemplo e como interpretar a saída e recuperar os ficheiros.

O que alcançámos com isto foi recuperar ficheiros fragmentados cujo registo MFT foi sobrescrito. Como reconstruímos o histórico parcial/completo de dataruns, podemos com certeza (pelo menos se o histórico completo for reconstruído) determinar se os dados de file slack pertenceram ou não ao ficheiro em questão.

Limitação. A reconstrução de dataruns está quebrada com UNICODE (ANSI está ok). A importação da saída do Mft2Csv está quebrada se o csv for UNICODE (ANSI está ok). Atualizações parciais a IndexRecords (IndexRoot/IndexAllocation) são muito difíceis de interpretar, pois provavelmente não temos conhecimento do índice original. Registos completos estão OK, no entanto. A circularidade de um ficheiro de 65 MB impõe uma restrição inerente e absoluta sobre quantas transações históricas do FS existem. Os systemdrives têm assim histórico limitado no $LogFile, enquanto discos externos/secundários têm mais transações históricas armazenadas. Pode aumentar o tamanho do $LogFile com chkdsk (chkdsk c: /L:262144). Alterações aos dados de ficheiros residentes não são armazenadas dentro do $LogFile, apenas a informação de que uma alteração foi feita é armazenada.

Nota O $UsnJrnl contém informação de forma mais amigável para humanos. Por exemplo, cada registo contém fileref, filename, timestamp e explicação do que ocorreu. Contém também muito mais informação histórica do que o $LogFile, embora sem muitos detalhes. Se o $UsnJrnl estiver ativo, então todas as transações escritas nele durante o ciclo de vida de reciclagem do $LogFile também estão presentes dentro do $LogFile. Isto significa que não há razão para decodificar o $UsnJrnl para compreender melhor o $LogFile.

Espaço slack Neste contexto, espaço slack significa o espaço dentro de um registo RCRD que é o remanescente no registo para além da última transação. Penso que isto não foi descrito antes, por isso deixe-me explicar. Volume slack é o espaço não utilizado entre o fim do sistema de ficheiros e o fim da partição onde o sistema de ficheiros reside. MFT record slack é mais ou menos o mesmo, mas refere-se ao espaço encontrado após a assinatura de fim de registo (0xFFFFFFFF) até ao fim físico do registo (0x400 ou 0x1000). E o espaço slack dentro do $LogFile é, portanto, o espaço encontrado para além da última transação e até ao fim do registo RCRD (normalmente 0x1000). Estas transações do slack estão na verdade lá desde antes de o $LogFile ter sido reciclado (sobrescrito). Existe também um algoritmo que identifica transações válidas a partir do espaço slack. Além disso, podem também existir várias camadas desse espaço slack. Exemplo: Digamos que a última transação num dado registo RCRD terminou no offset 0x00007D27. Deste offset até 0x00007FFF temos 0x2D8 bytes de espaço slack. Poderia então acontecer que os bytes a começar em 0x00007D28 não sejam um cabeçalho de transação válido porque está no meio de uma transação. O programa irá então (se configurado para tal) tentar reconstruir um pseudo-cabeçalho com valores válidos para decodificar a transação. Se falhar em reconstruir qualquer cabeçalho válido, considera que demasiada informação do cabeçalho original foi perdida, e considerará estes bytes como perdidos, e continuará a analisar o resto do espaço slack à procura de qualquer cabeçalho de transação válido. Os bytes perdidos serão registados em debug.log para investigar. Por outro lado, se conseguiu reconstruir um cabeçalho válido, a informação sobre isso será encontrada no campo lf_TextInformation. Digamos que identificou uma transação a começar no offset 0x00007D48 e com tamanho 0xB0. Então outra transação boa foi identificada imediatamente a seguir no offset 0x00007DF8 com tamanho 0xE0. No entanto, no offset 0x00007ED8 não havia cabeçalho de transação válido. Isto significa que estamos agora na segunda camada de espaço slack dentro desse registo RCRD. Agora digamos que o programa, após reanálise, conseguiu identificar um cabeçalho de transação válido no offset 0x00007F18. Esta transação seria marcada no csv com um valor de 2 no campo FromRcrdSlack. No entanto, considere o tamanho total da transação a empurrar o offset para além do tamanho do registo RCRD. Em essência, esta seria uma transação parcialmente recuperada, que poderia decodificar bem, mas será encontrada com um valor de 1 no campo IncompleteTransaction. Lembre-se que o debug.log é muito detalhado e ajudará a compreender a saída decodificada, especialmente o que vem do espaço slack.

Configuração de 32 bits vs 64 bits. Esta definição é importante configurar corretamente. Significa qual SO tratou o volume alvo. O ponto é que o tratamento de OpenAttributeTable difere entre SO de 32 bits e de 64 bits. Pode haver, naturalmente, casos (por exemplo, disco usb) em que o volume foi tratado por vários SO's diferentes, caso em que pode ser complicado obter esta definição 100% correta. A partir da versão 2.0.0.8 foi implementado um mecanismo de autodeteção. No entanto, continua a ser recomendado tentar configurar esta configuração corretamente. No campo TextEinformation será impressa uma mensagem "Mixed OS detected" quando detetar formato OpenAttributeTableDump que difere da configuração ou quando ambos os tipos são detetados. De qualquer forma, pode ser útil analisar o LogFile_OpenAttributeTable.csv para avaliar a saída. Se vir entradas com colunas contendo valores estranhos, então esta definição em particular pode estar errada. Se assim for, então a maioria dos valores está bastante errada. Por exemplo, a maioria dos campos AttributeType são UNKNOWN, Lsn não está dentro do intervalo atual, MftRef é demasiado alto e MftRefSeqNo de 0. Tenha em atenção que AttributeType é resolvido como UNKNOWN para entradas não inicializadas na tabela, mas estas são fáceis de identificar pois todos os valores após AllocatedOrNextFree são 0 e são perfeitamente válidos. Estes desafios parecem estar corrigidos com a autodeteção implementada na versão 2.0.0.8.Extração de atualizações de atributos residentes (UpdateResidentValue). A operação UpdateResidentValue destina-se a atualizações do conteúdo de atributos residentes. A configuração "Extract resident updates of min size" permite extrair a modificação binária do atributo residente. O campo de entrada é para o tamanho mínimo em bytes a extrair. O uso provavelmente mais interessante desta funcionalidade é com volumes geridos pelo Nt5.x (XP, 2003), onde as atualizações completas ao atributo $DATA (conteúdo normal de ficheiro) são armazenadas nos campos redo e undo com UpdateResidentValue. Ficheiros com conteúdo $DATA residente são ficheiros de tamanho menor, no máximo 744 bytes (com tamanho de registo MFT de 1024), mas geralmente menos. Os dados extraídos são escritos numa subpasta chamada ResidentExtract. Os ficheiros de saída são nomeados com uma lógica como esta; MFT($MFTRef)$OffsetInMft$AttributeOffset_LSN($Lsn)$Operation.bin. Por exemplo, MFT(1643)_0x0098_0x00B8_LSN(1415242628)redo.bin significaria registo MFT número 1643, o offset do atributo alvo no MFT é 0x98, o offset da modificação dentro do atributo alvo é 0xB8, o LSN da transação é 1415242628, e isto foi para uma operação redo. As extrações para operações undo contêm assim os dados nesse offset antes da modificação. A ativação desta funcionalidade irá desencadear algum output irrelevante e pouco interessante. A maioria dos falsos positivos é filtrada automaticamente, mas alguns são inevitáveis. Por exemplo, atualizações de $INDEX_ROOT, $ATTRIBUTE_LIST e $BITMAP podem ser incluídas. É possível, no entanto, rastrear manualmente os atributos para filtrar os que não são $DATA, comparando o OffsetInMft com o que é encontrado no relevante InitializeFileRecordSegment ou, se aplicável, no próprio $MFT. A partir da versão 2.0.0.13 foi adicionada a extração de $EA. Ver nota sobre atributos $EA.

Filenames csv A partir da versão 2.0.0.6 foi implementada uma nova funcionalidade para exportar todos os nomes de ficheiro identificados. A origem destas entradas vem de InitializeFileRecordSegment, UpdateNonResidentValue, AddindexEntryRoot, DeleteindexEntryRoot, AddIndexEntryAllocation, DeleteIndexEntryAllocation e WriteEndOfIndexBuffer. O csv com estes nomes de ficheiro, LogFile_FileNames.csv, contém assim um histórico reconstruído de todos os filename, MftRef e MftRefSeqNo durante a duração do histórico do $LogFile. Poderá assim ver todos os vários nomes de ficheiro que um determinado registo Mft teve durante o período de tempo coberto pelo $LogFile. Quando um ficheiro é renomeado, o MftrefSeqNo não é incrementado. Quando um registo MFT é marcado como eliminado e posteriormente reutilizado, o MftRefSeqNo é incrementado em um com a nova inicialização.

$TXF_DATA Com Transactional NTFS (TxF), haverá ocorrências do stream nomeado $TXF_DATA no atributo $LOGGED_UTILITY_STREAM. É sempre residente, e pode haver vários por ficheiro. O uso não é generalizado, e a Microsoft na verdade incentiva métodos alternativos. [quote]A Microsoft recomenda fortemente que os programadores utilizem meios alternativos para satisfazer as necessidades das suas aplicações.[/quote]. Parece que apenas alguns mecanismos de atualização de software o utilizam. Cada ficheiro/pasta criado com ele recebe um fileref único (não confundir com números de registo MFT). Este fileref único é o nome que o ficheiro terá quando for posteriormente eliminado (e movido para a pasta $Extend$RmMetadata$Txf). O atributo $DATA padrão sem nome do ficheiro $Tops contém informação sobre onde no $TxfLogContainer00000000000000000001 iria a próxima transação. O stream $DATA nomeado $T do $Tops contém dados reais (de operações de ficheiro transacionais) que são reciclados. Dentro de $TXF_DATA existe também um campo chamado LsnUserData que é um offset para o $TxfLogContainer00000000000000000001 onde muitos mais detalhes de transação são encontrados. LsnNtfsMetadata também contém um offset para o mesmo ficheiro $TxfLogContainer00000000000000000001. Note que estes offsets podem ser alterados numa fase posterior, e são então referidos numa operação UpdateResidentValue no $LogFile. O campo MftRef_RM_Root é o número de registo de ficheiro da raiz do gestor de recursos responsável pela transação associada a este ficheiro (o padrão é 5, que é o diretório raiz). Para atualizações de $TXF_DATA através de UpdateResidentValue, o texto "Partial update" é acrescentado no campo TextInformation. Por esta razão, podem também existir valores como 0x0000000000007E-- em LsnUserData. Isto porque um UpdateResidentValue de tamanho 31 bytes significa que os primeiros 3 membros da estrutura completa estão em falta, e também 1 byte de LsnUserData está em falta. O byte em falta é o "byte baixo", portanto 2 caracteres/nibbles de "-" cada, como substituição para indicar o byte desconhecido em falta (na verdade apenas o byte existente). Se o UpdateResidentValue fosse de 32 bytes, então não seriam necessários caracteres/nibbles de substituição, pois o LsnUserData completo foi fornecido.

debug.log Neste log são escritas mensagens de erro e informação verbosa. Se forem encontrados valores ou comentários estranhos no output, procure no debug.log pelo lsn. Normalmente a transação completa é exportada, o que pode ajudar a compreender. Para auxiliar investigações de transações, pode ser útil preencher uma lista separada por vírgulas de lsn's no campo de entrada. Então será impressa informação verbosa para esses lsn's.

$EA O atributo $EA é um conjunto de pares nome-valor e pensa-se que existem para compatibilidade com OS/2. Raramente se vê utilizado, embora algum malware o tenha usado. Pode haver vários pares por atributo, mas o tamanho máximo de todos é 65535 bytes. Só pode haver 1 atributo $EA por ficheiro. Conteúdo maior pode ser distribuído por vários ficheiros, como mostrado no PoC EaTools; https://github.com/jschicht/EaTools Atributos $EA existentes não podem ser modificados diretamente. Pares nome/valor adicionais podem ser acrescentados a qualquer momento, desde que o tamanho de todos os pares esteja abaixo de 0xFFFF bytes. O comportamento estranho deste atributo é que todo o conteúdo do $EA completo é escrito no $LogFile para qualquer novo par. Isto é tanto para conteúdo $EA residente como não residente. Isso significa que se um terceiro par nome/valor for adicionado a um $EA, todos os 3 pares são escritos no $LogFile, quer através de UpdateResidentValue quer de UpdateNonResidentValue.

Todo Implementar mais análise dos dados presentes em ntfs.db. Atualmente exigirá um certo nível de conhecimento de NTFS para compreender o output. Exportar conteúdo $EA não residente.

Uso em linha de comandos Se não forem fornecidos parâmetros, a GUI será iniciada por predefinição. Os switches válidos são:

Switches: /LogFileFile: $LogFile de entrada extraído. Obrigatório, a menos que seja usado /LogFileFragmentFile:. /LogFileFragmentFile: Opcionalmente, um fragmento de $LogFile de entrada. Pode ser qualquer fragmento quebrado com pelo menos 1 transação. /MftCsvFile: O csv de output do Mft2Csv mais recente. Opcional. /OutputPath: O caminho de output de todo o output do parser. Por predefinição, o diretório do programa. /TimeZone: Um valor de string para o fuso horário. Ver notas mais abaixo para valores válidos. /OutputFormat: O formato de output do csv. Valores válidos podem ser l2t, BodyFile, all. /BrokenMft: Valor booleano para lidar com MFT's com formato incorreto. O padrão é 0. Pode ser 0 ou 1. /SkipFixups: Valor booleano para ignorar fixups. Usado principalmente com memory dumps. O padrão é 0. Pode ser 0 ou 1. /Separator: O separador a usar no csv. O padrão é | /Unicode: Valor booleano para descodificar strings unicode. O padrão é 0. Pode ser 0 ou 1. /TSFormat: Um inteiro de 1 - 6 para especificar o formato de timestamp. Inicie a gui para ver o que significam. O padrão é 6. /TSPrecision: Que precisão usar no timestamp. Valores válidos são None, MilliSec e NanoSec. O padrão é NanoSec. /TSPrecisionSeparator: O separador a colocar na separação da precisão. O padrão é ".". Inicie a gui para ver o que significa. /TSPrecisionSeparator2: O separador a colocar entre MilliSec e NanoSec na precisão do timestamp. O padrão é vazio/nada. Inicie a gui para ver o que significa. /TSErrorVal: Um valor de erro personalizado a colocar com erros na descodificação de timestamp. O valor padrão é '0000-00-00 00:00:00', que é compatível com MySql, e representa um valor de timestamp inválido para NTFS. /ReconstructDataruns: Valor booleano para especificar se deve ser realizada a reconstrução de dataruns. O padrão é 0. Pode ser 0 ou 1. /MftRecordSize: O tamanho dos registos MFT. Valores válidos são 1024 e 4096. O padrão é 1024. /RebuildHeadersSlack: Valor booleano para especificar se deve tentar reconstruir o cabeçalho a partir de transações quebradas recuperadas do slack. O padrão é 0. Pode ser 0 ou 1. /SectorsPerCluster: Número de setores por cluster. O padrão é 8. Pode ser 1,2,4,8,16,32,64 e 128. /LsnErrorLevel: Um valor entre 0 e 1 (100%), como limiar para identificar transações válidas/inválidas a partir do slack, com base no lsn anterior. O padrão é 0.1 (10%). /SourceIs32bit: Valor booleano para especificar se o volume é originário de um sistema de 32 bits. O padrão é 0 (x64). Pode ser 0 ou 1. /ExtractDataUpdates: Valor booleano para especificar se deve ser realizada a extração de conteúdo de dados residentes. O padrão é 0. Pode ser 0 ou 1. /ExtractDataUpdatesSize: Valor para definir o tamanho mínimo em bytes do que extrair. Usado apenas com a definição ExtractDataUpdates. O padrão é 2 (bytes) como mínimo. /VerboseLsnList: Uma lista separada por vírgulas de lsn's que irão desencadear o modo verboso. A informação de registo verboso encontra-se em debug.log. /SkipSqlite3: Valor booleano para especificar se o parser deve omitir todas as operações sqlite3. Se o ntfs.db gerado (reconstrução de dataruns, importação do csv mft) não for usado, isto pode ser seguramente ignorado/omitido. O padrão é 0. Pode ser 0 ou 1. /VerifyFragment: Valor booleano para ativar uma validação simples apenas num fragmento, e não no parser completo. Pode ser 0 ou 1. Por predefinição, escreverá o fragmento corrigido em OutFragment.bin, a menos que especificado de outra forma em /OutFragmentName: /OutFragmentName: O nome do ficheiro de output onde escrever o fragmento corrigido, se /VerifyFragment: estiver definido como 1. Se omitido, o nome de ficheiro padrão é OutFragment.bin. /SkipFixups: Valor booleano para ignorar fixups. Usado com fragmentos reconstruídos. Ver exemplos. O padrão é 0. Pode ser 0 ou 1. /BrokenLogFile: Valor booleano para tratar o $LogFile como quebrado. Usado com RCRD's reconstruídos e irá contornar várias verificações de validação. O padrão é 0. Pode ser 0 ou 1.

Os TimeZone's disponíveis para usar são: -12.00 -11.00 -10.00 -9.30 -9.00 -8.00 -7.00 -6.00 -5.00 -4.30 -4.00 -3.30 -3.00 -2.00 -1.00 0.00 1.00 2.00 3.00 3.30 4.00 4.30 5.00 5.30 5.45 6.00 6.30 7.00 8.00 8.45 9.00 9.30 10.00 10.30 11.00 11.30 12.00 12.45 13.00 14.00

Níveis de erro Os atuais códigos de saída (erro) foram implementados em modo de linha de comandos, o que o torna mais adequado para scripting em lote.

  1. Não foi possível descodificar nenhuma transação válida. Output vazio.
  2. Foi detetado um parâmetro de entrada provavelmente incorreto. Na maioria das vezes será SectorsPerCluster, e mais raramente MftRecordSize. O padrão é SectorsPerCluster=8 e MftRecordSize=1024.
  3. O fragmento falhou a validação.
  4. Falha ao escrever o fragmento corrigido no output. A validação do fragmento, no entanto, foi bem-sucedida.

Assim, se obtiver %ERRORLEVEL% == 1 significa que nada foi descodificado, e se obtiver %ERRORLEVEL% == 2 então muito provavelmente o parâmetro SectorsPerCluster foi definido incorretamente.

Exemplos: LogFileParser.exe /LogFileFile:c:\temp$LogFile /TimeZone:2.00 /MftRecordSize:4096 /ExtractDataUpdates:1 /ExtractDataUpdatesSize:8 /SectorsPerCluster:64 /TSFormat:1 /TSPrecision:NanoSec /Unicode:1 LogFileParser.exe /LogFileFile:c:\temp$LogFile /TimeZone:-5.00 /MftRecordSize:1024 /SectorsPerCluster:1 /TSFormat:1 /TSPrecision:MilliSec /Unicode:0 LogFileParser.exe /LogFileFile:c:\temp$LogFile /TSFormat:3 /ReconstructDataruns:1 LogFileParser.exe /LogFileFile:c:\temp$LogFile /TimeZone:7.00 /MftRecordSize:1024 /TSFormat:2 /TSPrecision:None /SourceIs32bit:1 LogFileParser.exe /LogFileFile:c:\temp$LogFile /TimeZone:7.00 /MftRecordSize:1024 /TSFormat:2 /TSPrecision:None /SourceIs32bit:1 /SkipSqlite3:1 LogFileParser.exe /LogFileFile:c:\temp$LogFile /OutputPath:E:\LFP-Output LogFileParser.exe /LogFileFile:c:\temp$LogFile /MftCsvFile:c:\temp$MFT LogFileParser.exe /LogFileFragmentFile:c:\temp\fragment.bin /OutputPath:E:\LFP-Output LogFileParser.exe /LogFileFragmentFile:c:\temp\fragment.bin /OutputPath:E:\LFP-Output /VerifyFragment:1 LogFileParser.exe /LogFileFragmentFile:c:\temp\fragment.bin /OutputPath:E:\LFP-Output /VerifyFragment:1 /OutFragmentName:FragmentsRCRDCollection.bin LogFileParser.exe /LogFileFile:E:\LFP-Output\FragmentsRCRDCollection.bin /OutputPath:E:\LFP-Output /SkipFixups:1 /BrokenLogFile:1

O último exemplo é um básico que usa predefinições comuns que funcionam perfeitamente em muitos casos. Também compatível com importações MySql.

Referências: Windows Internals 6th Edition http://www.opensource.apple.com/source/ntfs/ntfs-80/kext/ntfs_logfile.h https://dl.dropbox.com/s/c0u980a53ipaq7h/CEIC-2012_Anti-Anti_Forensics.pptx?dl=1

Baixar ferramenta