Simplify to detect and print handshake packet contents
- Detect TCP SYN packets and protocol-specific handshakes - Print raw hex data in readable hex dump format with ASCII - Show actual packet contents for signature analysis
This commit is contained in:
@@ -177,53 +177,38 @@ class ProtocolBlockingService {
|
||||
}
|
||||
|
||||
static Future<void> _analyzeFullPayload(String hexPacketLine, String peerIP) async {
|
||||
print('🔍 DEEP PAYLOAD ANALYSIS for peer $peerIP');
|
||||
|
||||
// Extract hex bytes from tcpdump output
|
||||
final hexBytes = _extractHexBytes(hexPacketLine);
|
||||
|
||||
if (hexBytes.isEmpty) {
|
||||
print('❌ No hex payload data found');
|
||||
return;
|
||||
}
|
||||
|
||||
print('📊 Analyzing ${hexBytes.length} bytes of raw packet data');
|
||||
// Check if this looks like a handshake (first packet of connection)
|
||||
if (_isHandshakePacket(hexBytes)) {
|
||||
print('🤝 HANDSHAKE DETECTED FROM $peerIP');
|
||||
print('📦 RAW HEX DATA:');
|
||||
|
||||
// Convert hex to single string for nDPI analyzer
|
||||
final hexString = hexBytes.join('');
|
||||
// Print hex data in readable format
|
||||
for (int i = 0; i < hexBytes.length; i += 16) {
|
||||
final chunk = hexBytes.skip(i).take(16);
|
||||
final hexLine = chunk.map((h) => h.padLeft(2, '0')).join(' ');
|
||||
final asciiLine = chunk.map((h) {
|
||||
final byte = int.parse(h, radix: 16);
|
||||
return (byte >= 32 && byte <= 126) ? String.fromCharCode(byte) : '.';
|
||||
}).join();
|
||||
|
||||
try {
|
||||
// Use our nDPI analyzer for true protocol detection
|
||||
final result = await Process.run('./protocol_analyzer', [hexString]);
|
||||
|
||||
if (result.exitCode == 0) {
|
||||
final output = result.stdout.toString().trim();
|
||||
print('✅ nDPI DEEP ANALYSIS: $output');
|
||||
|
||||
// Parse protocol from nDPI output
|
||||
final protocolMatch = RegExp(r'"protocol":\s*"([^"]+)"').firstMatch(output);
|
||||
final categoryMatch = RegExp(r'"category":\s*"([^"]+)"').firstMatch(output);
|
||||
|
||||
if (protocolMatch != null) {
|
||||
final protocol = protocolMatch.group(1) ?? 'Unknown';
|
||||
final category = categoryMatch?.group(1) ?? 'Unknown';
|
||||
|
||||
print('🎯 PAYLOAD PROTOCOL: $protocol (Category: $category)');
|
||||
|
||||
if (_shouldBlockProtocol(protocol, category)) {
|
||||
print('🚫 BLOCKING PAYLOAD-DETECTED PROTOCOL: $protocol');
|
||||
// TODO: Implement actual blocking
|
||||
} else {
|
||||
print('✅ ALLOWING PAYLOAD-DETECTED PROTOCOL: $protocol');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print('⚠️ nDPI analyzer failed, using fallback payload analysis');
|
||||
await _fallbackPayloadAnalysis(hexBytes, peerIP);
|
||||
print('${i.toString().padLeft(4, '0')}: ${hexLine.padRight(48)} |$asciiLine|');
|
||||
}
|
||||
} catch (e) {
|
||||
print('❌ Error running nDPI analyzer: $e');
|
||||
await _fallbackPayloadAnalysis(hexBytes, peerIP);
|
||||
|
||||
// Also show raw ASCII if readable
|
||||
final asciiData = _extractAsciiFromHex(hexBytes);
|
||||
final readableAscii = asciiData.replaceAll(RegExp(r'[^\x20-\x7E]'), '.');
|
||||
if (readableAscii.contains(RegExp(r'[a-zA-Z]'))) {
|
||||
print('📝 ASCII: $readableAscii');
|
||||
}
|
||||
|
||||
print('═══════════════════════════════════════');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -773,6 +758,51 @@ class ProtocolBlockingService {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool _isHandshakePacket(List<String> hexBytes) {
|
||||
if (hexBytes.length < 20) return false;
|
||||
|
||||
// Check for TCP SYN packet (handshake initiation)
|
||||
if (hexBytes.length >= 34) {
|
||||
// IP header is first 20 bytes, TCP header starts at byte 20
|
||||
// TCP flags are at offset 33 (13th byte of TCP header)
|
||||
try {
|
||||
final tcpFlags = int.parse(hexBytes[33], radix: 16);
|
||||
// Check for SYN flag (0x02) - indicates handshake
|
||||
if (tcpFlags & 0x02 != 0) {
|
||||
return true;
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore parsing errors
|
||||
}
|
||||
}
|
||||
|
||||
// Check for common handshake patterns in payload
|
||||
final asciiData = _extractAsciiFromHex(hexBytes);
|
||||
|
||||
// BitTorrent handshake starts with 19 + "BitTorrent protocol"
|
||||
if (hexBytes.length >= 20 && hexBytes[0] == '13') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// HTTP requests
|
||||
if (asciiData.startsWith('GET ') || asciiData.startsWith('POST ') ||
|
||||
asciiData.startsWith('HEAD ') || asciiData.startsWith('PUT ')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// TLS Client Hello
|
||||
if (hexBytes.length >= 6 && hexBytes[0] == '16' && hexBytes[1] == '03') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// SSH handshake
|
||||
if (asciiData.startsWith('SSH-')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static List<String> _extractHexBytes(String tcpdumpOutput) {
|
||||
final hexPattern = RegExp(r'0x[0-9a-f]+:\s*([0-9a-f\s]+)', caseSensitive: false);
|
||||
final matches = hexPattern.allMatches(tcpdumpOutput);
|
||||
|
||||
Reference in New Issue
Block a user