Created
March 30, 2019 12:13
-
-
Save wfjsw/a1e894c5a1093526efa9e465afaa7b10 to your computer and use it in GitHub Desktop.
Script snippet used to check MTProxy availability.
This file contains 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
var Uint64BE, Int64BE, Uint64LE, Int64LE; !function (E) { var g, A = "undefined", U = A !== typeof Buffer && Buffer, I = A !== typeof Uint8Array && Uint8Array, L = A !== typeof ArrayBuffer && ArrayBuffer, d = [0, 0, 0, 0, 0, 0, 0, 0], n = Array.isArray || function (t) { return !!t && "[object Array]" == Object.prototype.toString.call(t) }, w = 4294967296; function t(t, r, a) { var c = r ? 0 : 4, y = r ? 4 : 0, n = r ? 0 : 3, e = r ? 1 : 2, o = r ? 2 : 1, i = r ? 3 : 0, u = r ? k : J, s = r ? O : _, f = l.prototype, h = "is" + t, v = "_" + h; return f.buffer = void 0, f.offset = 0, f[v] = !0, f.toNumber = p, f.toString = function (t) { var r = this.buffer, f = this.offset, n = B(r, f + c), e = B(r, f + y), o = "", i = !a && 2147483648 & n; i && (n = ~n, e = w - e); t = t || 10; for (; ;) { var u = n % t * w + e; if (n = Math.floor(n / t), e = Math.floor(u / t), o = (u % t).toString(t) + o, !n && !e) break } i && (o = "-" + o); return o }, f.toJSON = p, f.toArray = m, U && (f.toBuffer = S), I && (f.toArrayBuffer = j), l[h] = function (t) { return !(!t || !t[v]) }, E[t] = l; function l(t, r, f, n) { return this instanceof l ? function (t, r, f, n, e) { I && L && (r instanceof L && (r = new I(r)), n instanceof L && (n = new I(n))); if (!(r || f || n || g)) return void (t.buffer = N(d, 0)); if (!x(r, f)) { var o = g || Array; e = f, n = r, f = 0, r = new o(8) } if (t.buffer = r, t.offset = f |= 0, A === typeof n) return; "string" == typeof n ? function (t, r, f, n) { var e = 0, o = f.length, i = 0, u = 0; "-" === f[0] && e++; var a = e; for (; e < o;) { var s = parseInt(f[e++], n); if (!(0 <= s)) break; u = u * n + s, i = i * n + Math.floor(u / w), u %= w } a && (i = ~i, u ? u = w - u : i++); b(t, r + c, i), b(t, r + y, u) }(r, f, n, e || 10) : x(n, e) ? M(r, f, n, e) : "number" == typeof e ? (b(r, f + c, n), b(r, f + y, e)) : 0 < n ? u(r, f, n) : n < 0 ? s(r, f, n) : M(r, f, d, 0) }(this, t, r, f, n) : new l(t, r, f, n) } function p() { var t = this.buffer, r = this.offset, f = B(t, r + c), n = B(t, r + y); return a || (f |= 0), f ? f * w + n : n } function b(t, r, f) { t[r + i] = 255 & f, f >>= 8, t[r + o] = 255 & f, f >>= 8, t[r + e] = 255 & f, f >>= 8, t[r + n] = 255 & f } function B(t, r) { return 16777216 * t[r + n] + (t[r + e] << 16) + (t[r + o] << 8) + t[r + i] } } function m(t) { var r = this.buffer, f = this.offset; return g = null, !1 !== t && n(r) ? 8 === r.length ? r : r.slice(f, f + 8) : N(r, f) } function S(t) { var r = this.buffer, f = this.offset; return g = U, !1 !== t && U.isBuffer(r) ? 8 === r.length ? r : r.slice(f, f + 8) : U.from(j.call(this, t)) } function j(t) { var r = this.buffer, f = this.offset, n = r.buffer; if (g = I, !1 !== t && !r.offset && n instanceof L) return 8 === n.byteLength ? n : n.slice(f, f + 8); var e = new I(8); return M(e, 0, r, f), e.buffer } function x(t, r) { var f = t && t.length; return r |= 0, f && r + 8 <= f && "string" != typeof t[r] } function M(t, r, f, n) { r |= 0, n |= 0; for (var e = 0; e < 8; e++)t[r++] = 255 & f[n++] } function N(t, r) { return Array.prototype.slice.call(t, r, r + 8) } function k(t, r, f) { for (var n = r + 8; r < n;)t[--n] = 255 & f, f /= 256 } function O(t, r, f) { var n = r + 8; for (f++; r < n;)t[--n] = 255 & -f ^ 255, f /= 256 } function J(t, r, f) { for (var n = r + 8; r < n;)t[r++] = 255 & f, f /= 256 } function _(t, r, f) { var n = r + 8; for (f++; r < n;)t[r++] = 255 & -f ^ 255, f /= 256 } Uint64BE = t("Uint64BE", !0, !0), Int64BE = t("Int64BE", !0, !1), Uint64LE = t("Uint64LE", !1, !0), Int64LE = t("Int64LE", !1, !1) }("object" == typeof exports && "string" != typeof exports.nodeName ? exports : this || {}); | |
const net = require('net') | |
const crypto = require('crypto') | |
exports.pingDirect = () => new Promise((rs, rj) => { | |
try { | |
const start_time = Date.now() | |
let pack_creation_time | |
const client = net.connect(443, '149.154.167.50') | |
client.on('ready', () => { | |
const intermediate_time = Date.now() | |
let msg_id_num = Date.now() / 1000 * Math.pow(2, 32) | |
while (msg_id_num % 4 !== 0) { | |
msg_id_num++ | |
} | |
const msg_id_raw = new Uint64LE(msg_id_num) | |
const msg_id = msg_id_raw.toBuffer() | |
const msg = Buffer.concat([Buffer.from('78974660', 'hex'), Buffer.allocUnsafe(16)]) | |
const msg_data_length = Buffer.from('14000000', 'hex') | |
const auth_key_id = Buffer.allocUnsafe(8).fill(0) | |
const data_pack = Buffer.concat([auth_key_id, msg_id, msg_data_length, msg]) | |
const intermediate_header = Buffer.from('eeeeeeee', 'hex') | |
const data_length = Buffer.alloc(4) | |
data_length.writeUInt32LE(data_pack.length) | |
const data = Buffer.concat([intermediate_header, data_length, data_pack]) | |
pack_creation_time = Date.now() - intermediate_time | |
client.write(data) | |
}) | |
client.setTimeout(10000, () => { | |
client.destroy(new Error('timeout')) | |
}) | |
client.on('data', (chunk) => { | |
const time_lapse = Date.now() - start_time - pack_creation_time | |
const res_str = chunk.toString('hex') | |
client.end() | |
if (res_str.indexOf('63241605') > -1) { | |
console.log(time_lapse) | |
rs(time_lapse) | |
} else { | |
rj(new Error('invalid response')) | |
} | |
}) | |
client.on('error', e => rj(e)) | |
} catch (e) { | |
rj(e) | |
} | |
}) | |
exports.pingIntermediate = (ip, port, secret) => new Promise((rs, rj) => { | |
// plain[8 + 32(prekey) + 16(iv)] + enc[4(tag) + 2(dc_idx, signed le)] | |
try { | |
const secbin = Buffer.from(secret, 'hex') | |
const encprekey = crypto.randomBytes(32) | |
const enciv = crypto.randomBytes(16) | |
const enc_key = crypto.createHash('sha256').update(Buffer.concat([encprekey, secbin])).digest() | |
const revmix = Buffer.concat([encprekey, enciv]).reverse() | |
const decprekey = revmix.slice(0, 32) | |
const deciv = revmix.slice(32, 48) | |
const dec_key = crypto.createHash('sha256').update(Buffer.concat([decprekey, secbin])).digest() | |
const handshake_pkg = Buffer.concat([crypto.randomBytes(8), encprekey, enciv, Buffer.from('eeeeeeee', 'hex'), Buffer.from('02000000', 'hex')]) | |
const encryptor = crypto.createCipheriv('aes-256-ctr', enc_key, enciv) | |
const decryptor = crypto.createDecipheriv('aes-256-ctr', dec_key, deciv) | |
const encrypted_handshake_pkg = encryptor.update(handshake_pkg) | |
const real_handshake_pkg = Buffer.concat([handshake_pkg.slice(0, 56), encrypted_handshake_pkg.slice(56, 64)]) | |
const start_time = Date.now() | |
let pack_creation_time | |
const client = net.connect(port, ip) | |
client.setTimeout(5000) | |
client.on('timeout', () => { | |
client.destroy(new Error('timeout')) | |
}) | |
client.on('ready', () => { | |
const intermediate_time = Date.now() | |
let msg_id_num = Date.now() / 1000 * Math.pow(2, 32) | |
while (msg_id_num % 4 !== 0) { | |
msg_id_num++ | |
} | |
const msg_id_raw = new Uint64LE(msg_id_num) | |
const msg_id = msg_id_raw.toBuffer() | |
const msg = Buffer.concat([Buffer.from('78974660', 'hex'), Buffer.allocUnsafe(16)]) | |
const msg_data_length = Buffer.from('14000000', 'hex') | |
const auth_key_id = Buffer.allocUnsafe(8).fill(0) | |
const data_pack = Buffer.concat([auth_key_id, msg_id, msg_data_length, msg]) | |
const data_length = Buffer.alloc(4) | |
data_length.writeUInt32LE(data_pack.length) | |
const data = Buffer.concat([data_length, data_pack]) | |
const enc_data = encryptor.update(data) | |
const pack = Buffer.concat([real_handshake_pkg, enc_data]) | |
pack_creation_time = Date.now() - intermediate_time | |
client.write(pack) | |
}) | |
client.on('data', (chunk) => { | |
const time_lapse = Date.now() - start_time - pack_creation_time | |
const raw_data = decryptor.update(chunk) | |
const res_str = raw_data.toString('hex') | |
client.end() | |
try { | |
encryptor.final() | |
decryptor.final() | |
} catch (e) { | |
//ignore | |
} | |
if (res_str.indexOf('63241605') > -1) { | |
console.log(time_lapse) | |
rs(time_lapse) | |
} else { | |
rj(new Error('invalid response')) | |
} | |
}) | |
client.on('error', e => { | |
try { | |
encryptor.final() | |
decryptor.final() | |
} catch (e) { | |
//ignore | |
} | |
rj(e) | |
}) | |
} catch (e) { | |
rj(e) | |
} | |
}) | |
exports.pingSecure = (ip, port, secret) => new Promise((rs, rj) => { | |
// plain[8 + 32(prekey) + 16(iv)] + enc[4(tag) + 2(dc_idx, signed le)] | |
try { | |
const secbin = Buffer.from(secret, 'hex') | |
const encprekey = crypto.randomBytes(32) | |
const enciv = crypto.randomBytes(16) | |
const enc_key = crypto.createHash('sha256').update(Buffer.concat([encprekey, secbin])).digest() | |
const revmix = Buffer.concat([encprekey, enciv]).reverse() | |
const decprekey = revmix.slice(0, 32) | |
const deciv = revmix.slice(32, 48) | |
const dec_key = crypto.createHash('sha256').update(Buffer.concat([decprekey, secbin])).digest() | |
const handshake_pkg = Buffer.concat([crypto.randomBytes(8), encprekey, enciv, Buffer.from('dddddddd', 'hex'), Buffer.from('02000000', 'hex')]) | |
const encryptor = crypto.createCipheriv('aes-256-ctr', enc_key, enciv) | |
const decryptor = crypto.createDecipheriv('aes-256-ctr', dec_key, deciv) | |
const encrypted_handshake_pkg = encryptor.update(handshake_pkg) | |
const real_handshake_pkg = Buffer.concat([handshake_pkg.slice(0, 56), encrypted_handshake_pkg.slice(56, 64)]) | |
const start_time = Date.now() | |
let pack_creation_time | |
const client = net.connect(port, ip) | |
client.setTimeout(5000) | |
client.on('timeout', () => { | |
client.destroy(new Error('timeout')) | |
}) | |
client.on('ready', () => { | |
const intermediate_time = Date.now() | |
let msg_id_num = Date.now() / 1000 * Math.pow(2, 32) | |
while (msg_id_num % 4 !== 0) { | |
msg_id_num++ | |
} | |
const msg_id_raw = new Uint64LE(msg_id_num) | |
const msg_id = msg_id_raw.toBuffer() | |
const msg = Buffer.concat([Buffer.from('78974660', 'hex'), Buffer.allocUnsafe(16)]) | |
const msg_data_length = Buffer.from('14000000', 'hex') | |
const auth_key_id = Buffer.allocUnsafe(8).fill(0) | |
const data_pack = Buffer.concat([auth_key_id, msg_id, msg_data_length, msg]) | |
const padding_length = Math.floor(Math.random() * 4) | |
const padding = crypto.randomBytes(padding_length) | |
const data_length = Buffer.alloc(4) | |
data_length.writeUInt32LE(data_pack.length + padding_length) | |
const data = Buffer.concat([data_length, data_pack, padding]) | |
const enc_data = encryptor.update(data) | |
const pack = Buffer.concat([real_handshake_pkg, enc_data]) | |
pack_creation_time = Date.now() - intermediate_time | |
client.write(pack) | |
}) | |
client.on('data', (chunk) => { | |
const time_lapse = Date.now() - start_time - pack_creation_time | |
const raw_data = decryptor.update(chunk) | |
const res_str = raw_data.toString('hex') | |
client.end() | |
try { | |
encryptor.final() | |
decryptor.final() | |
} catch (e) { | |
//ignore | |
} | |
if (res_str.indexOf('63241605') > -1) { | |
console.log(time_lapse) | |
rs(time_lapse) | |
} else { | |
rj(new Error('invalid response')) | |
} | |
}) | |
client.on('error', e => { | |
try { | |
encryptor.final() | |
decryptor.final() | |
} catch (e) { | |
//ignore | |
} | |
rj(e) | |
}) | |
} catch (e) { | |
rj(e) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment