tcpの場合、synパケットのみをキャッチします。
tcpdump -n "tcp[tcpflags] & (tcp-syn) != 0"
udpの場合、すべての着信udpパケット
tcpdump -n inbound and udp
理論的には、tcpdumpからの出力をファイルにリダイレクトし、必要に応じてさらに解析できますが、それでも私はその変態です。したがって、nodecpでtcpdumpをリッスンし、結果をmysqlデータベースに保存するサービスを作成します。
必要なすべてのスクリプトのヘッダー:
#!/usr/bin/nodejs 'use strict'; const net = require('net'); const spawn = require('child_process').spawn; const mysql = require('mysql2'); const config = require('./config'); const connection = mysql.createConnection(config.mysql); const tcpdump = spawn('tcpdump', ['-n', 'tcp[tcpflags] & (tcp-syn) != 0']); const excludePorts = [ 80 ]; const excludeAddrs = [ '127.0.0.1', ]; let lastTcpLine = '';
lastTcpLine-stdoutから受信した最後の行を一時的に保存するために必要です。 データは行ごとではなく、最後の行が完全ではない可能性のあるブロックごとに取得されるため、その後半は2番目のデータブロックと共に到着します。
独自の接続の一部を除外するにはexcludePortsとexcludeAddrsが必要です。 ポート80に別の拡張ロガーがあり、ローカルホストもリッスンしません。
リスナーを切断します。
tcpdump.stdout.on('data', (data) => { let lines = `${data}`.split('\n'); // // lastTcpLine , lastTcpLine let lastTcpLineNum = lines.length - 1; let toNum = lines.length - 1; lines[ 0 ] = lines[ 0 ] + lastTcpLine; if( lines[ lastTcpLineNum ].indexOf('\n') == -1 ) { lastTcpLine = lines[ lastTcpLineNum ]; toNum --; } else lastTcpLine = ''; for(let i=0; i<=toNum; i++) { saveLog( parseLine(lines[ i ], 'tcp') ); // } });
IPはaddress.portの形式で、たとえば192.168.1.1.443で到着し、アドレスとポートに解析します。
function parseLine(line, proto) { let parts = line.split(' '); // let dstAddrParts = parseIP(parts[ 4 ]); // , let srcAddrParts = parseIP(parts[ 2 ]); // return { addr: srcAddrParts.addr, port: dstAddrParts.port, proto: proto, req_time: parseInt(new Date() / 1000), }; } function parseIP(ipStr) { let addrParts = ipStr.split('.'); // , let port = addrParts[ addrParts.length - 1 ]; // - let ipOctets = []; // for(let i=0; i<=(addrParts.length-2); i++) ipOctets.push(addrParts[ i ]); let addr = ipOctets.join('.'); if( !net.isIP(addr) ) // , , , - , null addr = null; return { addr: addr, port: parseInt(port) }; }
結果をデータベースに保存します。
function saveLog(info) { if( excludePorts.indexOf(info.port) > -1 ) // - return; if( excludeAddrs.indexOf(info.addr) > -1 ) // - return; for(let key in info) // - - if( !info[ key ] ) { console.log('Bad info:', info); return; } let fields = []; // for(let key in info) fields.push('`' + key + '`'); let values = []; // for(let key in info) { if( typeof(info[ key ]) == 'number' ) values.push(info[ key ]); else values.push(`'` + info[ key ] + `'`); } let query = 'INSERT INTO access_logs (' + fields.join(',') + ') VALUES(' + values.join(',') + ')'; // connection.query(query); }
udpリスナーのコードは100%同じです。繰り返しはしません。ソースコードはgithub.com/hololoev/honeypot_tcpdump_logger.gitで見ることができます。
今、新しいvirtualochkaが必要です。その上にnginxと「Under construction」スタブとロガーを配置します。 私たちはそれにドメインを向けません;平均的なウェブマスターである、新たに作成されたサーバーの外観をあらゆる方法で描写します。 数日後(5月5日から5月9日まで)に結果が得られます。
総住所 | tcpスキャン | UDPスキャン | HTTPスキャン |
---|---|---|---|
4324 | 38558 | 543 | 101 |
上位5つのTCPポート:
TCPポート | スキャン |
---|---|
445 | 2538 |
23 | 1515 |
22 | 1304 |
3306 | 151 |
3389 | 148 |
上位5つのudpポート:
UDPポート | スキャン |
---|---|
5060 | 95 |
161 | 41 |
1900 | 32 |
123 | 30 |
137 | 23 |
最もアクティブな上位10個のIPアドレス:
住所 | 合計スキャン | 場所 | http | tcp | UDP |
---|---|---|---|---|---|
40.115.124.127 | 25822 | IE /ダブリン | 0 | 25822 | 0 |
77.72.82.101 | 861 | RU / | 0 | 861 | 0 |
77.72.82.22 | 760 | RU / | 0 | 760 | 0 |
145.239.134.1 | 550 | GB / | 0 | 550 | 0 |
101.128.72.140 | 282 | ID /ジャカルタ | 0 | 282 | 0 |
77.72.85.25 | 244 | RU / | 0 | 244 | 0 |
181.214.87.34 | 208 | 米国/ラスベガス | 0 | 208 | 0 |
5.188.11.91 | 189 | RU /サンクトペテルブルク | 0 | 189 | 0 |
128.199.141.239 | 173 | SG /シンガポール | 0 | 173 | 0 |
5.188.11.79 | 156 | RU /サンクトペテルブルク | 0 | 156 | 0 |
最もアクティブな上位100個のアドレスを使用してマップします。