ハニーポット-nodejsおよびtcpdumpのロガー

みなさんこんにちは。 最近の同志 R_Volandは彼のhttpハニポットについて話しました。 彼は私にこの投稿を書くよう促しました。 しかし、この場合、httpだけでなく、すべてのtcpおよびudpスキャンをキャッチします。 tcpdumpを使用してリクエストをキャッチします。



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個のアドレスを使用してマップします。










All Articles