Created
December 2, 2015 04:34
-
-
Save zachary822/937ac765cc7d6ffbde06 to your computer and use it in GitHub Desktop.
Send TCP SYN with node.js and raw-socket package
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Sending a TCP SYN packet properly using the raw-socket package. | |
*/ | |
var raw = require('raw-socket'); | |
var crypto = require('crypto'); | |
// create a raw socket using TCP | |
var s = raw.createSocket({ | |
protocol: raw.Protocol.TCP | |
}); | |
/** | |
* generate pseudo-header. Used to calculate package checksum. | |
* @param {number} srcIp - source ip as an integer | |
* @param {number} dstIp - destination ip as an integer | |
* @param {number} tcpPacketLength - tcp packet length | |
* @return {Buffer} the pseudo-header, used later | |
*/ | |
var genPseudoHeader = function (srcIp, dstIp, tcpPacketLength) { | |
// new buffer of length 12. The pseudo-header length | |
var pseudoHeader = new Buffer(12); | |
// Important to fill with zeroes. Node.js does not zero the memory before creating the buffer. | |
pseudoHeader.fill(0); | |
pseudoHeader.writeUInt32BE(srcIp, 0); // write source ip, a 32 bit integer! | |
pseudoHeader.writeUInt32BE(dstIp, 4); // write destination ip, a 32 bit integer! | |
pseudoHeader.writeUInt8(6, 9); // specifies protocol. Here we write 6 for TCP. Other protocols have other numbers. | |
// Write the TCP packet length of which we are generating a pseudo-header for. | |
// Does not include the length of the psuedo-header. | |
pseudoHeader.writeUInt16BE(tcpPacketLength, 10); | |
return pseudoHeader; | |
}; | |
/** | |
* generate SYN packet | |
* @param {number} srcIp - source ip as an integer | |
* @param {number} dstIp - destination ip as an integer | |
* @param {number} srcPort - source port | |
* @param {number} dstPort - destination port | |
* @return {Buffer} the TCP SYN packet | |
*/ | |
var genSynPacket = function (srcIp, dstIp, srcPort, dstPort) { | |
// A scaffolding TCP syn packet. Notice all zeroes except a few options. | |
// The "few options" include setting the SYN flags. | |
// Don't change it if you don't know what you're doing. | |
var p = new Buffer('0000000000000000000000005002200000000000', 'hex'); | |
// Need 4 random bytes as sequence. Needs to be random to avoid collision. | |
// You can choose your own random source. I chose the crypto module. | |
crypto.randomBytes(4).copy(p, 4); | |
p.writeUInt16BE(srcPort, 0); // Write source port | |
p.writeUInt16BE(dstPort, 2); // Write destination port | |
// generate checksum with utility function | |
// using a pseudo header and the tcp packet scaffold | |
var sum = raw.createChecksum(genPseudoHeader(srcIp, dstIp, p.length), p); | |
// writing the checksum back to the packet. Packet complete! | |
p.writeUInt16BE(sum, 16); | |
return p; | |
}; | |
// generate the packet. | |
var p = genSynPacket(srcIp, dstIp, srcPort, dstPort) | |
// send packet with offset 0, length = packet.length, to the dstIP | |
// The port data is in the packet already, so we don't worry about that during sending. | |
// Open tcpdump or wireshark and watch the not quite three way handshake. Useful to test for open ports. | |
s.send(p, 0, p.length, dstIp, function () { | |
console.log("sent TCP SYN"); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment