Skip to main content
Glama

extract_credentials

Identify and extract potential credentials (HTTP Basic Auth, FTP, Telnet) from PCAP files for LLM-driven threat analysis and network diagnostics using WireMCP.

Instructions

Extract potential credentials (HTTP Basic Auth, FTP, Telnet) from a PCAP file for LLM analysis

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pcapPathYesPath to the PCAP file to analyze (e.g., ./demo.pcap)

Implementation Reference

  • Full handler implementation for the 'extract_credentials' tool. Captures plaintext credentials from HTTP Basic Auth (decoded), FTP, Telnet, and formats Kerberos hashes from PCAP files using tshark for LLM analysis and cracking.
    server.tool(
        'extract_credentials',
        'Extract potential credentials (HTTP Basic Auth, FTP, Telnet) from a PCAP file for LLM analysis',
        {
          pcapPath: z.string().describe('Path to the PCAP file to analyze (e.g., ./demo.pcap)'),
        },
        async (args) => {
          try {
            const tsharkPath = await findTshark();
            const { pcapPath } = args;
            console.error(`Extracting credentials from PCAP file: ${pcapPath}`);
      
            await fs.access(pcapPath);
      
            // Extract plaintext credentials
            const { stdout: plaintextOut } = await execAsync(
              `${tsharkPath} -r "${pcapPath}" -T fields -e http.authbasic -e ftp.request.command -e ftp.request.arg -e telnet.data -e frame.number`,
              { env: { ...process.env, PATH: `${process.env.PATH}:/usr/bin:/usr/local/bin:/opt/homebrew/bin` } }
            );
    
            // Extract Kerberos credentials
            const { stdout: kerberosOut } = await execAsync(
              `${tsharkPath} -r "${pcapPath}" -T fields -e kerberos.CNameString -e kerberos.realm -e kerberos.cipher -e kerberos.type -e kerberos.msg_type -e frame.number`,
              { env: { ...process.env, PATH: `${process.env.PATH}:/usr/bin:/usr/local/bin:/opt/homebrew/bin` } }
            );
    
            const lines = plaintextOut.split('\n').filter(line => line.trim());
            const packets = lines.map(line => {
              const [authBasic, ftpCmd, ftpArg, telnetData, frameNumber] = line.split('\t');
              return {
                authBasic: authBasic || '',
                ftpCmd: ftpCmd || '',
                ftpArg: ftpArg || '',
                telnetData: telnetData || '',
                frameNumber: frameNumber || ''
              };
            });
      
            const credentials = {
              plaintext: [],
              encrypted: []
            };
      
            // Process HTTP Basic Auth
            packets.forEach(p => {
              if (p.authBasic) {
                const [username, password] = Buffer.from(p.authBasic, 'base64').toString().split(':');
                credentials.plaintext.push({ type: 'HTTP Basic Auth', username, password, frame: p.frameNumber });
              }
            });
      
            // Process FTP
            packets.forEach(p => {
              if (p.ftpCmd === 'USER') {
                credentials.plaintext.push({ type: 'FTP', username: p.ftpArg, password: '', frame: p.frameNumber });
              }
              if (p.ftpCmd === 'PASS') {
                const lastUser = credentials.plaintext.findLast(c => c.type === 'FTP' && !c.password);
                if (lastUser) lastUser.password = p.ftpArg;
              }
            });
      
            // Process Telnet
            packets.forEach(p => {
              if (p.telnetData) {
                const telnetStr = p.telnetData.trim();
                if (telnetStr.toLowerCase().includes('login:') || telnetStr.toLowerCase().includes('password:')) {
                  credentials.plaintext.push({ type: 'Telnet Prompt', data: telnetStr, frame: p.frameNumber });
                } else if (telnetStr && !telnetStr.match(/[A-Z][a-z]+:/) && !telnetStr.includes(' ')) {
                  const lastPrompt = credentials.plaintext.findLast(c => c.type === 'Telnet Prompt');
                  if (lastPrompt && lastPrompt.data.toLowerCase().includes('login:')) {
                    credentials.plaintext.push({ type: 'Telnet', username: telnetStr, password: '', frame: p.frameNumber });
                  } else if (lastPrompt && lastPrompt.data.toLowerCase().includes('password:')) {
                    const lastUser = credentials.plaintext.findLast(c => c.type === 'Telnet' && !c.password);
                    if (lastUser) lastUser.password = telnetStr;
                    else credentials.plaintext.push({ type: 'Telnet', username: '', password: telnetStr, frame: p.frameNumber });
                  }
                }
              }
            });
    
            // Process Kerberos credentials
            const kerberosLines = kerberosOut.split('\n').filter(line => line.trim());
            kerberosLines.forEach(line => {
              const [cname, realm, cipher, type, msgType, frameNumber] = line.split('\t');
              
              if (cipher && type) {
                let hashFormat = '';
                // Format hash based on message type
                if (msgType === '10' || msgType === '30') { // AS-REQ or TGS-REQ
                  hashFormat = '$krb5pa$23$';
                  if (cname) hashFormat += `${cname}$`;
                  if (realm) hashFormat += `${realm}$`;
                  hashFormat += cipher;
                } else if (msgType === '11') { // AS-REP
                  hashFormat = '$krb5asrep$23$';
                  if (cname) hashFormat += `${cname}@`;
                  if (realm) hashFormat += `${realm}$`;
                  hashFormat += cipher;
                }
    
                if (hashFormat) {
                  credentials.encrypted.push({
                    type: 'Kerberos',
                    hash: hashFormat,
                    username: cname || 'unknown',
                    realm: realm || 'unknown',
                    frame: frameNumber,
                    crackingMode: msgType === '11' ? 'hashcat -m 18200' : 'hashcat -m 7500'
                  });
                }
              }
            });
    
            console.error(`Found ${credentials.plaintext.length} plaintext and ${credentials.encrypted.length} encrypted credentials`);
      
            const outputText = `Analyzed PCAP: ${pcapPath}\n\n` +
              `Plaintext Credentials:\n${credentials.plaintext.length > 0 ? 
                credentials.plaintext.map(c => 
                  c.type === 'Telnet Prompt' ? 
                    `${c.type}: ${c.data} (Frame ${c.frame})` : 
                    `${c.type}: ${c.username}:${c.password} (Frame ${c.frame})`
                ).join('\n') : 
                'None'}\n\n` +
              `Encrypted/Hashed Credentials:\n${credentials.encrypted.length > 0 ?
                credentials.encrypted.map(c =>
                  `${c.type}: User=${c.username} Realm=${c.realm} (Frame ${c.frame})\n` +
                  `Hash=${c.hash}\n` +
                  `Cracking Command: ${c.crackingMode}\n`
                ).join('\n') :
                'None'}\n\n` +
              `Note: Encrypted credentials can be cracked using tools like John the Ripper or hashcat.\n` +
              `For Kerberos hashes:\n` +
              `- AS-REQ/TGS-REQ: hashcat -m 7500 or john --format=krb5pa-md5\n` +
              `- AS-REP: hashcat -m 18200 or john --format=krb5asrep`;
      
            return {
              content: [{ type: 'text', text: outputText }],
            };
          } catch (error) {
            console.error(`Error in extract_credentials: ${error.message}`);
            return { content: [{ type: 'text', text: `Error: ${error.message}` }], isError: true };
          }
        }
      );
  • Input schema for the 'extract_credentials' tool defining the required pcapPath parameter.
    {
      pcapPath: z.string().describe('Path to the PCAP file to analyze (e.g., ./demo.pcap)'),
    },
  • index.js:366-366 (registration)
    Registration of the tool name in server.tool call.
    'extract_credentials',
  • Associated prompt template 'extract_credentials_prompt' for guiding LLM usage of the tool.
    server.prompt(
      'extract_credentials_prompt',
      {
        pcapPath: z.string().describe('Path to the PCAP file'),
      },
      ({ pcapPath }) => ({
        messages: [{
          role: 'user',
          content: {
            type: 'text',
            text: `Please analyze the PCAP file at ${pcapPath} for potential credential exposure:
    1. Look for plaintext credentials (HTTP Basic Auth, FTP, Telnet)
    2. Identify Kerberos authentication attempts
    3. Extract any hashed credentials
    4. Provide security recommendations for credential handling`
          }
        }]
      })
    );
Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/0xKoda/WireMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server