ハニーポット-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スキャン
432438558543101


上位5つのTCPポート:
TCPポートスキャン
4452538
231515
221304
3306151
3389148


上位5つのudpポート:
UDPポートスキャン
506095
16141
190032
12330
13723


最もアクティブな上位10個のIPアドレス:
住所合計スキャン場所httptcpUDP
40.115.124.12725822IE /ダブリン0258220
77.72.82.101861RU /08610
77.72.82.22760RU /07600
145.239.134.1550GB /05500
101.128.72.140282ID /ジャカルタ02820
77.72.85.25244RU /02440
181.214.87.34208米国/ラスベガス02080
5.188.11.91189RU /サンクトペテルブルク01890
128.199.141.239173SG /シンガポール01730
5.188.11.79156RU /サンクトペテルブルク01560


最もアクティブな上位100個のアドレスを使用してマップします。

Source: https://habr.com/ru/post/J358214/


All Articles