Skip to main content
Glama

test_web_application

Conducts technology-specific penetration testing on web applications to identify security vulnerabilities based on detected technologies like WordPress, Apache, or PHP.

Instructions

Technology-specific web application penetration testing

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
targetYesTarget web application URL
technologiesYesDetected technologies (e.g., ['WordPress', 'Apache', 'PHP'])

Implementation Reference

  • The core handler function that executes the test_web_application tool. It performs technology-specific tests for CMS like WordPress (using WPScan), Drupal, Joomla, web servers, and common web vulnerabilities (Nikto). Aggregates findings and generates recommendations.
    async testWebApplication(target: string, technologies: string[]): Promise<ScanResult> {
      try {
        console.error(`🔍 Testing Web Application on ${target}`);
        
        const findings: string[] = [];
        const results: any = {};
        
        // Test 1: Technology-specific tests
        for (const tech of technologies) {
          const techLower = tech.toLowerCase();
          
          if (techLower.includes('wordpress')) {
            const wpResults = await this.testWordPress(target);
            results.wordpress_tests = wpResults;
            if (wpResults.plugins_detected) {
              findings.push(`WordPress plugins detected: ${wpResults.plugins_detected.length}`);
            }
          }
          
          if (techLower.includes('drupal')) {
            const drupalResults = await this.testDrupal(target);
            results.drupal_tests = drupalResults;
          }
          
          if (techLower.includes('joomla')) {
            const joomlaResults = await this.testJoomla(target);
            results.joomla_tests = joomlaResults;
          }
          
          if (techLower.includes('apache') || techLower.includes('nginx')) {
            const webServerResults = await this.testWebServer(target, techLower);
            results.webserver_tests = webServerResults;
          }
        }
    
        // Test 2: Common web vulnerabilities
        const webVulnResults = await this.testWebVulnerabilities(target);
        results.web_vulnerabilities = webVulnResults;
        findings.push(...webVulnResults.findings);
    
        return {
          target,
          timestamp: new Date().toISOString(),
          tool: 'web_application_test',
          results: {
            service: 'Web Application',
            technologies_tested: technologies,
            findings,
            detailed_results: results,
            recommendations: this.getWebAppRecommendations(findings, technologies)
          },
          status: 'success'
        };
        
      } catch (error) {
        return {
          target,
          timestamp: new Date().toISOString(),
          tool: 'web_application_test',
          results: {},
          status: 'error',
          error: error instanceof Error ? error.message : String(error)
        };
      }
    }
  • Input schema definition for the test_web_application tool, specifying required parameters: target (string) and technologies (array of strings). Part of the tool registration in ListTools response.
    name: "test_web_application",
    description: "Technology-specific web application penetration testing",
    inputSchema: {
      type: "object",
      properties: {
        target: { type: "string", description: "Target web application URL" },
        technologies: { 
          type: "array", 
          items: { type: "string" },
          description: "Detected technologies (e.g., ['WordPress', 'Apache', 'PHP'])" 
        }
      },
      required: ["target", "technologies"]
    }
  • src/index.ts:577-578 (registration)
    Tool dispatch/registration in the CallToolRequest handler switch statement, routing calls to the serviceSpecificTools.testWebApplication method.
    case "test_web_application":
      return respond(await this.serviceSpecificTools.testWebApplication(args.target, args.technologies));
  • src/index.ts:378-392 (registration)
    Tool object registration in the ListToolsRequest handler, defining name, description, and input schema for client discovery.
      name: "test_web_application",
      description: "Technology-specific web application penetration testing",
      inputSchema: {
        type: "object",
        properties: {
          target: { type: "string", description: "Target web application URL" },
          technologies: { 
            type: "array", 
            items: { type: "string" },
            description: "Detected technologies (e.g., ['WordPress', 'Apache', 'PHP'])" 
          }
        },
        required: ["target", "technologies"]
      }
    },
  • Supporting helper methods called by the main handler: testWordPress (WPScan), testDrupal (droopescan), testJoomla (joomscan), testWebServer (headers), testWebVulnerabilities (Nikto).
      }
      
      // SMB/NetBIOS Testing with cross-platform support
      async testSMB(target: string, port: number = 445): Promise<ScanResult> {
        try {
          console.error(`🔍 Testing SMB service on ${target}:${port}`);
          
          const findings: string[] = [];
          const results: any = {};
          
          // Test 1: SMB enumeration (platform-specific)
          if (isWindows) {
            // Windows: Use built-in commands
            try {
              const { stdout: netViewOutput } = await execAsync(`net view \\\\${target}`, { timeout: 60000 });
              results.net_view = netViewOutput;
              
              if (netViewOutput.includes('Shared resources')) {
                findings.push('SMB shares enumerated successfully via net view');
              }
            } catch (e) {
              console.error('net view failed:', e);
            }
            
            // Windows: NBTStat for NetBIOS enumeration
            try {
              const { stdout: nbtstatOutput } = await execAsync(`nbtstat -A ${target}`, { timeout: 30000 });
              results.nbtstat = nbtstatOutput;
              
              if (nbtstatOutput.includes('<20>')) {
                findings.push('NetBIOS file sharing service detected');
              }
              if (nbtstatOutput.includes('<00>')) {
                findings.push('NetBIOS workstation service detected');
              }
            } catch (e) {
              console.error('nbtstat failed:', e);
            }
          } else {
            // Linux/Mac: Use traditional tools
            try {
              const { stdout: enum4linuxOutput } = await execAsync(`enum4linux -a ${target}`, { timeout: 120000 });
              results.enum4linux = enum4linuxOutput;
              
              if (enum4linuxOutput.includes('Domain Name:')) {
                findings.push('Domain information disclosed');
              }
              if (enum4linuxOutput.includes('password policy')) {
                findings.push('Password policy information disclosed');
              }
            } catch (e) {
              console.error('enum4linux failed:', e);
            }
            
            try {
              const { stdout: smbclientOutput } = await execAsync(`smbclient -L ${target} -N`, { timeout: 60000 });
              results.smbclient_shares = smbclientOutput;
              
              if (smbclientOutput.includes('Sharename')) {
                findings.push('SMB shares enumerated successfully');
              }
              if (smbclientOutput.includes('IPC$')) {
                findings.push('IPC$ share accessible');
              }
            } catch (e) {
              console.error('smbclient enumeration failed:', e);
            }
          }
          
          // Test 2: CrackMapExec (works on all platforms if installed)
          try {
            const cmeCommand = isWindows ? 'python -m crackmapexec' : 'crackmapexec';
            const { stdout: cmeOutput } = await execAsync(`${cmeCommand} smb ${target}`, { timeout: 60000 });
            results.crackmapexec = cmeOutput;
            
            if (cmeOutput.includes('SMBv1:True')) {
              findings.push('SMBv1 enabled (security risk)');
            }
            if (cmeOutput.includes('signing:False')) {
              findings.push('SMB signing disabled (security risk)');
            }
          } catch (e) {
            console.error('CrackMapExec failed:', e);
          }
          
          // Test 3: Check for EternalBlue vulnerability (nmap works on all platforms)
          try {
            const { stdout: nmapOutput } = await execAsync(`nmap -p ${port} --script smb-vuln-ms17-010 ${target}`, { timeout: 120000 });
            results.eternalblue_check = nmapOutput;
            
            if (nmapOutput.includes('VULNERABLE')) {
              findings.push('CRITICAL: EternalBlue vulnerability detected (CVE-2017-0144)');
            }
          } catch (e) {
            console.error('EternalBlue check failed:', e);
          }
          
          // Test 4: PowerShell SMB testing (Windows only)
          if (isWindows) {
            try {
              const psScript = `
                $target = "${target}"
                try {
                  $result = Test-NetConnection -ComputerName $target -Port ${port}
                  if ($result.TcpTestSucceeded) {
                    Write-Output "SMB port ${port} is accessible"
                    
                    # Try to enumerate shares
                    $shares = Get-SmbShare -CimSession $target -ErrorAction SilentlyContinue
                    if ($shares) {
                      Write-Output "Available shares:"
                      $shares | ForEach-Object { Write-Output "  - $($_.Name)" }
                    }
                  }
                } catch {
                  Write-Output "Error: $($_.Exception.Message)"
                }
              `;
              
              const { stdout: psOutput } = await execAsync(`powershell -Command "${psScript}"`, { timeout: 60000 });
              results.powershell_smb = psOutput;
              
              if (psOutput.includes('is accessible')) {
                findings.push('SMB service confirmed accessible via PowerShell');
              }
              if (psOutput.includes('Available shares:')) {
                findings.push('SMB shares enumerated via PowerShell');
              }
            } catch (e) {
              console.error('PowerShell SMB test failed:', e);
            }
          } else {
            // Test 5: SMB null session test (Linux/Mac)
            try {
              const { stdout: nullSessionOutput } = await execAsync(`rpcclient -U "" -N ${target} -c "enumdomusers"`, { timeout: 60000 });
              results.null_session = nullSessionOutput;
              
              if (nullSessionOutput.includes('user:')) {
                findings.push('SMB null session allows user enumeration');
              }
            } catch (e) {
              console.error('Null session test failed:', e);
            }
          }
          
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'smb_comprehensive_test',
            results: {
              service: 'SMB',
              port,
              findings,
              detailed_results: results,
              recommendations: this.getSMBRecommendations(findings)
            },
            status: 'success'
          };
          
        } catch (error) {
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'smb_comprehensive_test',
            results: {},
            status: 'error',
            error: error instanceof Error ? error.message : String(error)
          };
        }
      }
      
      // SSH Testing
      async testSSH(target: string, port: number = 22): Promise<ScanResult> {
        try {
          console.error(`🔍 Testing SSH service on ${target}:${port}`);
          
          const findings: string[] = [];
          const results: any = {};
          
          // Test 1: SSH audit
          try {
            const { stdout: auditOutput } = await execAsync(`ssh-audit ${target}:${port}`, { timeout: 60000 });
            results.ssh_audit = auditOutput;
            
            if (auditOutput.includes('WARN')) {
              findings.push('SSH configuration warnings detected');
            }
            if (auditOutput.includes('FAIL')) {
              findings.push('SSH configuration failures detected');
            }
          } catch (e) {
            console.error('SSH audit failed:', e);
          }
          
          // Test 2: Banner grabbing and version detection (cross-platform)
          try {
            let bannerCommand = '';
            if (isWindows) {
              // Windows: Use PowerShell
              bannerCommand = `powershell -Command "try { $client = New-Object System.Net.Sockets.TcpClient('${target}', ${port}); $stream = $client.GetStream(); $buffer = New-Object byte[] 1024; $read = $stream.Read($buffer, 0, 1024); $banner = [System.Text.Encoding]::ASCII.GetString($buffer, 0, $read); Write-Output $banner; $client.Close() } catch { Write-Output 'Connection failed' }"`;
            } else {
              // Linux/Mac: Use netcat or telnet
              bannerCommand = `timeout 10 bash -c "echo '' | nc -w 3 ${target} ${port}" || timeout 10 telnet ${target} ${port} 2>/dev/null | head -n 1`;
            }
            
            const { stdout: bannerOutput } = await execAsync(bannerCommand, { timeout: 15000 });
            results.banner = bannerOutput;
            
            if (bannerOutput.includes('OpenSSH') || bannerOutput.includes('SSH')) {
              const versionMatch = bannerOutput.match(/OpenSSH[_\s]*([\d.]+)/i) || bannerOutput.match(/SSH[_\s]*([\d.]+)/i);
              if (versionMatch) {
                results.ssh_version = versionMatch[1];
                findings.push(`SSH version detected: ${versionMatch[1]}`);
              } else {
                findings.push('SSH service detected');
              }
            }
          } catch (e) {
            console.error('Banner grab failed:', e);
          }
          
          // Test 3: SSH key algorithms and ciphers
          try {
            const { stdout: nmapOutput } = await execAsync(`nmap -p ${port} --script ssh2-enum-algos ${target}`, { timeout: 60000 });
            results.ssh_algorithms = nmapOutput;
            
            if (nmapOutput.includes('weak')) {
              findings.push('Weak SSH algorithms detected');
            }
          } catch (e) {
            console.error('SSH algorithm enumeration failed:', e);
          }
          
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'ssh_comprehensive_test',
            results: {
              service: 'SSH',
              port,
              findings,
              detailed_results: results,
              recommendations: this.getSSHRecommendations(findings)
            },
            status: 'success'
          };
          
        } catch (error) {
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'ssh_comprehensive_test',
            results: {},
            status: 'error',
            error: error instanceof Error ? error.message : String(error)
          };
        }
      }
      
      // FTP Testing
      async testFTP(target: string, port: number = 21): Promise<ScanResult> {
        try {
          console.error(`🔍 Testing FTP service on ${target}:${port}`);
          
          const findings: string[] = [];
          const results: any = {};
          
          // Test 1: Anonymous FTP access
          try {
            const { stdout: anonOutput } = await execAsync(`ftp -n ${target} ${port} << EOF
    user anonymous anonymous
    ls
    quit
    EOF`, { timeout: 30000 });
            results.anonymous_access = anonOutput;
            
            if (anonOutput.includes('230')) {
              findings.push('Anonymous FTP access allowed');
            }
          } catch (e) {
            console.error('Anonymous FTP test failed:', e);
          }
          
          // Test 2: FTP banner and version detection
          try {
            const { stdout: bannerOutput } = await execAsync(`nc -nv ${target} ${port} < /dev/null`, { timeout: 10000 });
            results.banner = bannerOutput;
            
            if (bannerOutput.includes('220')) {
              findings.push('FTP banner retrieved');
              if (bannerOutput.includes('vsftpd 2.3.4')) {
                findings.push('CRITICAL: vsftpd 2.3.4 backdoor vulnerability detected');
              }
            }
          } catch (e) {
            console.error('FTP banner grab failed:', e);
          }
          
          // Test 3: FTP bounce attack test
          try {
            const { stdout: nmapOutput } = await execAsync(`nmap -p ${port} --script ftp-bounce ${target}`, { timeout: 60000 });
            results.bounce_attack = nmapOutput;
            
            if (nmapOutput.includes('bounce')) {
              findings.push('FTP bounce attack possible');
            }
          } catch (e) {
            console.error('FTP bounce test failed:', e);
          }
          
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'ftp_comprehensive_test',
            results: {
              service: 'FTP',
              port,
              findings,
              detailed_results: results,
              recommendations: this.getFTPRecommendations(findings)
            },
            status: 'success'
          };
          
        } catch (error) {
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'ftp_comprehensive_test',
            results: {},
            status: 'error',
            error: error instanceof Error ? error.message : String(error)
          };
        }
      }
      
      // Database Testing (MySQL/PostgreSQL/MSSQL)
      async testDatabase(target: string, port: number, dbType: 'mysql' | 'postgres' | 'mssql'): Promise<ScanResult> {
        try {
          console.error(`🔍 Testing ${dbType.toUpperCase()} service on ${target}:${port}`);
          
          const findings: string[] = [];
          const results: any = {};
          
          // Test 1: Default credentials test
          const defaultCreds = this.getDefaultDatabaseCredentials(dbType);
          for (const cred of defaultCreds) {
            try {
              let testCommand = '';
              
              switch (dbType) {
                case 'mysql':
                  testCommand = `mysql -h ${target} -P ${port} -u ${cred.username} -p${cred.password} -e "SELECT VERSION();"`;
                  break;
                case 'postgres':
                  testCommand = `PGPASSWORD=${cred.password} psql -h ${target} -p ${port} -U ${cred.username} -d postgres -c "SELECT version();"`;
                  break;
                case 'mssql':
                  testCommand = `sqlcmd -S ${target},${port} -U ${cred.username} -P ${cred.password} -Q "SELECT @@VERSION"`;
                  break;
              }
              
              const { stdout: credOutput } = await execAsync(testCommand, { timeout: 30000 });
              if (credOutput && !credOutput.includes('ERROR') && !credOutput.includes('failed')) {
                findings.push(`Default credentials work: ${cred.username}/${cred.password}`);
                results.default_credentials = cred;
              }
            } catch (e) {
              // Expected for wrong credentials
            }
          }
          
          // Test 2: Database enumeration with nmap scripts
          try {
            let scriptName = '';
            switch (dbType) {
              case 'mysql':
                scriptName = 'mysql-info,mysql-enum';
                break;
              case 'postgres':
                scriptName = 'pgsql-brute';
                break;
              case 'mssql':
                scriptName = 'ms-sql-info,ms-sql-empty-password';
                break;
            }
            
            const { stdout: nmapOutput } = await execAsync(`nmap -p ${port} --script ${scriptName} ${target}`, { timeout: 120000 });
            results.nmap_enumeration = nmapOutput;
            
            if (nmapOutput.includes('version')) {
              findings.push('Database version information disclosed');
            }
          } catch (e) {
            console.error('Database enumeration failed:', e);
          }
          
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: `${dbType}_comprehensive_test`,
            results: {
              service: dbType.toUpperCase(),
              port,
              findings,
              detailed_results: results,
              recommendations: this.getDatabaseRecommendations(findings, dbType)
            },
            status: 'success'
          };
          
        } catch (error) {
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: `${dbType}_comprehensive_test`,
            results: {},
            status: 'error',
            error: error instanceof Error ? error.message : String(error)
          };
        }
      }
      
      // RDP Testing
      async testRDP(target: string, port: number = 3389): Promise<ScanResult> {
        try {
          console.error(`🔍 Testing RDP service on ${target}:${port}`);
          
          const findings: string[] = [];
          const results: any = {};
          
          // Test 1: BlueKeep vulnerability check
          try {
            const { stdout: bluekeepOutput } = await execAsync(`nmap -p ${port} --script rdp-vuln-ms12-020 ${target}`, { timeout: 120000 });
            results.bluekeep_check = bluekeepOutput;
            
            if (bluekeepOutput.includes('VULNERABLE')) {
              findings.push('CRITICAL: BlueKeep vulnerability detected (CVE-2019-0708)');
            }
          } catch (e) {
            console.error('BlueKeep check failed:', e);
          }
          
          // Test 2: RDP enumeration
          try {
            const { stdout: rdpEnumOutput } = await execAsync(`nmap -p ${port} --script rdp-enum-encryption ${target}`, { timeout: 60000 });
            results.rdp_enumeration = rdpEnumOutput;
            
            if (rdpEnumOutput.includes('CredSSP')) {
              findings.push('CredSSP supported');
            }
            if (rdpEnumOutput.includes('TLS')) {
              findings.push('TLS encryption supported');
            }
          } catch (e) {
            console.error('RDP enumeration failed:', e);
          }
          
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'rdp_comprehensive_test',
            results: {
              service: 'RDP',
              port,
              findings,
              detailed_results: results,
              recommendations: this.getRDPRecommendations(findings)
            },
            status: 'success'
          };
          
        } catch (error) {
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'rdp_comprehensive_test',
            results: {},
            status: 'error',
            error: error instanceof Error ? error.message : String(error)
          };
        }
      }
      
      // SNMP Testing
      async testSNMP(target: string, port: number = 161): Promise<ScanResult> {
        try {
          console.error(`🔍 Testing SNMP service on ${target}:${port}`);
          
          const findings: string[] = [];
          const results: any = {};
          
          // Test 1: SNMP community string enumeration
          const commonCommunities = ['public', 'private', 'community', 'admin', 'manager'];
          
          for (const community of commonCommunities) {
            try {
              const { stdout: snmpOutput } = await execAsync(`snmpwalk -v2c -c ${community} ${target}:${port} 1.3.6.1.2.1.1.1.0`, { timeout: 30000 });
              if (snmpOutput && !snmpOutput.includes('Timeout')) {
                findings.push(`SNMP community string found: ${community}`);
                results[`community_${community}`] = snmpOutput;
              }
            } catch (e) {
              // Expected for wrong community strings
            }
          }
          
          // Test 2: SNMP version detection
          try {
            const { stdout: versionOutput } = await execAsync(`nmap -p ${port} --script snmp-info ${target}`, { timeout: 60000 });
            results.snmp_version = versionOutput;
            
            if (versionOutput.includes('SNMPv1')) {
              findings.push('SNMPv1 detected (insecure)');
            }
          } catch (e) {
            console.error('SNMP version detection failed:', e);
          }
          
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'snmp_comprehensive_test',
            results: {
              service: 'SNMP',
              port,
              findings,
              detailed_results: results,
              recommendations: this.getSNMPRecommendations(findings)
            },
            status: 'success'
          };
          
        } catch (error) {
          return {
            target,
            timestamp: new Date().toISOString(),
            tool: 'snmp_comprehensive_test',
            results: {},
            status: 'error',
            error: error instanceof Error ? error.message : String(error)
          };
        }
      }
      
      // Helper methods for recommendations
      private getSMBRecommendations(findings: string[]): string[] {
        const recommendations: string[] = [];
        
        if (findings.some(f => f.includes('SMBv1'))) {
          recommendations.push('Disable SMBv1 protocol');
        }
        if (findings.some(f => f.includes('signing:False'))) {
          recommendations.push('Enable SMB signing');
        }
        if (findings.some(f => f.includes('EternalBlue'))) {
          recommendations.push('Apply MS17-010 security patch immediately');
        }
        if (findings.some(f => f.includes('null session'))) {
          recommendations.push('Disable SMB null sessions');
        }
        
        recommendations.push('Implement strong authentication');
        recommendations.push('Use SMBv3 with encryption');
        
        return recommendations;
      }
      
      private getSSHRecommendations(findings: string[]): string[] {
        const recommendations: string[] = [];
        
        if (findings.some(f => f.includes('weak'))) {
          recommendations.push('Update SSH configuration to use strong algorithms');
        }
        
        recommendations.push('Disable root login');
        recommendations.push('Use key-based authentication');
        recommendations.push('Implement fail2ban for brute force protection');
        recommendations.push('Change default SSH port');
        
        return recommendations;
      }
      
      private getFTPRecommendations(findings: string[]): string[] {
        const recommendations: string[] = [];
        
        if (findings.some(f => f.includes('Anonymous'))) {
          recommendations.push('Disable anonymous FTP access');
        }
        if (findings.some(f => f.includes('vsftpd 2.3.4'))) {
          recommendations.push('URGENT: Update vsftpd to latest version');
        }
        if (findings.some(f => f.includes('bounce'))) {
          recommendations.push('Disable FTP bounce attacks');
        }
        
        recommendations.push('Use SFTP instead of FTP');
        recommendations.push('Implement strong authentication');
        
        return recommendations;
      }
      
      private getDatabaseRecommendations(findings: string[], dbType: string): string[] {
        const recommendations: string[] = [];
        
        if (findings.some(f => f.includes('Default credentials'))) {
          recommendations.push('Change default database credentials');
        }
        
        recommendations.push('Implement strong password policies');
        recommendations.push('Use database firewall rules');
        recommendations.push('Enable database audit logging');
        recommendations.push('Use encrypted connections (SSL/TLS)');
        recommendations.push('Implement least privilege access');
        
        return recommendations;
      }
      
      private getRDPRecommendations(findings: string[]): string[] {
        const recommendations: string[] = [];
        
        if (findings.some(f => f.includes('BlueKeep'))) {
          recommendations.push('URGENT: Apply BlueKeep security patches');
        }
        
        recommendations.push('Enable Network Level Authentication (NLA)');
        recommendations.push('Use strong authentication');
        recommendations.push('Implement account lockout policies');
        recommendations.push('Use VPN for remote access');
        recommendations.push('Change default RDP port');
        
        return recommendations;
      }
      
      private getSNMPRecommendations(findings: string[]): string[] {
        const recommendations: string[] = [];
        
        if (findings.some(f => f.includes('community string'))) {
          recommendations.push('Change default SNMP community strings');
        }
        if (findings.some(f => f.includes('SNMPv1'))) {
          recommendations.push('Upgrade to SNMPv3 with authentication and encryption');
        }
        
        recommendations.push('Implement SNMP access control lists');
        recommendations.push('Use strong community strings');
        recommendations.push('Disable SNMP if not needed');
        
        return recommendations;
      }
      
      private getDefaultDatabaseCredentials(dbType: string): Array<{username: string, password: string}> {
        switch (dbType) {
          case 'mysql':
            return [
              { username: 'root', password: '' },
              { username: 'root', password: 'root' },
              { username: 'root', password: 'mysql' },
              { username: 'admin', password: 'admin' },
              { username: 'mysql', password: 'mysql' }
            ];
          case 'postgres':
            return [
              { username: 'postgres', password: '' },
              { username: 'postgres', password: 'postgres' },
              { username: 'postgres', password: 'admin' },
              { username: 'admin', password: 'admin' }
            ];
          case 'mssql':
            return [
              { username: 'sa', password: '' },
              { username: 'sa', password: 'sa' },
              { username: 'sa', password: 'admin' },
              { username: 'admin', password: 'admin' }
            ];
          default:
            return [];
        }
      }
    
      private getADRecommendations(findings: string[]): string[] {
        const recommendations: string[] = [];
        
        if (findings.some(f => f.includes('Domain Controller'))) {
          recommendations.push('Ensure Domain Controller is properly hardened');
          recommendations.push('Implement least privilege access controls');
          recommendations.push('Enable Advanced Audit Policy Configuration');
        }
        
        if (findings.some(f => f.includes('SYSVOL') || f.includes('NETLOGON'))) {
          recommendations.push('Secure SYSVOL and NETLOGON shares with proper permissions');
          recommendations.push('Monitor access to domain controller shares');
        }
        
        if (findings.some(f => f.includes('RID cycling'))) {
          recommendations.push('CRITICAL: Implement measures to prevent user enumeration');
          recommendations.push('Consider disabling null session enumeration');
        }
        
        if (findings.some(f => f.includes('Kerberoasting'))) {
          recommendations.push('Review Service Principal Names (SPNs)');
          recommendations.push('Use strong passwords for service accounts');
          recommendations.push('Consider using Group Managed Service Accounts (gMSA)');
        }
        
        recommendations.push('Implement Windows Event Forwarding (WEF)');
        recommendations.push('Deploy Microsoft Defender for Identity');
        recommendations.push('Regular security assessments using BloodHound');
        
        return recommendations;
      }
    
      private getWebAppRecommendations(findings: string[], technologies: string[]): string[] {
        const recommendations: string[] = [];
        
        if (technologies.some(tech => tech.toLowerCase().includes('wordpress'))) {
          recommendations.push('Keep WordPress core, themes, and plugins updated');
          recommendations.push('Use strong admin credentials and two-factor authentication');
          recommendations.push('Implement Web Application Firewall (WAF)');
        }
        
        if (findings.some(f => f.includes('plugin'))) {
          recommendations.push('Audit and remove unnecessary plugins');
          recommendations.push('Implement plugin vulnerability scanning');
        }
        
        if (findings.some(f => f.includes('SQL injection'))) {
          recommendations.push('CRITICAL: Fix SQL injection vulnerabilities immediately');
          recommendations.push('Implement parameterized queries');
        }
        
        if (findings.some(f => f.includes('XSS'))) {
          recommendations.push('Implement proper input validation and output encoding');
          recommendations.push('Use Content Security Policy (CSP) headers');
        }
        
        recommendations.push('Regular security testing and code reviews');
        recommendations.push('Implement secure coding practices');
        recommendations.push('Monitor application logs for suspicious activity');
        
        return recommendations;
      }
    
      // WordPress-specific testing
      private async testWordPress(target: string): Promise<any> {
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. While 'penetration testing' implies potentially intrusive/destructive actions, the description doesn't disclose critical behavioral traits: whether it requires authentication, what kind of tests it runs (e.g., automated vs. manual), rate limits, potential impact on target systems, or output format. This leaves significant gaps for safe and effective tool invocation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient phrase that communicates the core purpose without unnecessary words. It's appropriately sized for a tool with two well-documented parameters and no output schema, with every word earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a penetration testing tool with no annotations and no output schema, the description is insufficiently complete. It doesn't address safety considerations, expected outputs, or how it differs from numerous sibling testing tools. Given the potentially destructive nature of pentesting and the rich ecosystem of alternatives, more context is needed for effective tool selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters adequately. The description adds no additional parameter semantics beyond what's in the schema - it doesn't explain how 'technologies' array influences the testing approach or provide examples beyond the schema's basic description. This meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool performs 'web application penetration testing' with a 'technology-specific' focus, providing a specific verb+resource combination. However, it doesn't explicitly differentiate itself from sibling tools like 'nikto_scan', 'nuclei_scan', or 'sqlmap_scan' which also appear to be web application testing tools, leaving some ambiguity about its unique scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With many sibling tools for web application testing (e.g., nikto_scan, nuclei_scan, sqlmap_scan, burp_active_scan), there's no indication of prerequisites, appropriate contexts, or exclusions. The agent must infer usage from the name and description alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/adriyansyah-mf/mcp-pentest'

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