Skip to content

Instantly share code, notes, and snippets.

@wwhtrbbtt
Created May 4, 2023 20:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wwhtrbbtt/1bebfa7d2fe8e21c90f3777255aee0f3 to your computer and use it in GitHub Desktop.
Save wwhtrbbtt/1bebfa7d2fe8e21c90f3777255aee0f3 to your computer and use it in GitHub Desktop.
const net = require('node:net');
const tls = require('node:tls');
const fs = require('node:fs');
const { Duplex } = require('node:stream');
const { Buffer } = require('node:buffer');
const createChannel = function () {
let promiseResolve;
let promise = new Promise((resolve) => {
promiseResolve = resolve;
});
return {
write: promiseResolve,
read: () => {
return promise;
},
};
};
const tlsChan = createChannel();
const fromBytes = (...bytes) => {
const buf = Buffer.from([...bytes]);
return parseInt(buf.toString('hex'), 16);
};
const GREASE = [
0x0a0a, 0x0a0a, 0x1a1a, 0x2a2a, 0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a,
0x8a8a, 0x9a9a, 0xaaaa, 0xbaba, 0xcaca, 0xdada, 0xeaea, 0xfafa, 0xa0a,
];
const CIPHER_SUITES = {
0x00: 'TLS_NULL_WITH_NULL_NULL',
0x01: 'TLS_RSA_WITH_NULL_MD5',
0x02: 'TLS_RSA_WITH_NULL_SHA',
0x03: 'TLS_RSA_EXPORT_WITH_RC4_40_MD5',
0x04: 'TLS_RSA_WITH_RC4_128_MD5',
0x05: 'TLS_RSA_WITH_RC4_128_SHA',
0x06: 'TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5',
0x07: 'TLS_RSA_WITH_IDEA_CBC_SHA',
0x08: 'TLS_RSA_EXPORT_WITH_DES40_CBC_SHA',
0x09: 'TLS_RSA_WITH_DES_CBC_SHA',
0x0a: 'TLS_RSA_WITH_3DES_EDE_CBC_SHA',
0x0b: 'TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA',
0x0c: 'TLS_DH_DSS_WITH_DES_CBC_SHA',
0x0d: 'TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA',
0x0e: 'TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA',
0x0f: 'TLS_DH_RSA_WITH_DES_CBC_SHA',
0x10: 'TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA',
0x11: 'TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA',
0x12: 'TLS_DHE_DSS_WITH_DES_CBC_SHA',
0x13: 'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA',
0x14: 'TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA',
0x15: 'TLS_DHE_RSA_WITH_DES_CBC_SHA',
0x16: 'TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA',
0x17: 'TLS_DH_anon_EXPORT_WITH_RC4_40_MD5',
0x18: 'TLS_DH_anon_WITH_RC4_128_MD5',
0x19: 'TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA',
0x1a: 'TLS_DH_anon_WITH_DES_CBC_SHA',
0x1b: 'TLS_DH_anon_WITH_3DES_EDE_CBC_SHA',
0x1c: 'SSL_FORTEZZA_KEA_WITH_NULL_SHA',
0x1d: 'SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA',
// https://github.com/openssl/openssl/issues/6710
// 0x1e: "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA",
0x1e: 'TLS_KRB5_WITH_DES_CBC_SHA',
0x1f: 'TLS_KRB5_WITH_3DES_EDE_CBC_SHA',
0x20: 'TLS_KRB5_WITH_RC4_128_SHA',
0x21: 'TLS_KRB5_WITH_IDEA_CBC_SHA',
0x22: 'TLS_KRB5_WITH_DES_CBC_MD5',
0x23: 'TLS_KRB5_WITH_3DES_EDE_CBC_MD5',
0x24: 'TLS_KRB5_WITH_RC4_128_MD5',
0x25: 'TLS_KRB5_WITH_IDEA_CBC_MD5',
0x26: 'TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA',
0x27: 'TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA',
0x28: 'TLS_KRB5_EXPORT_WITH_RC4_40_SHA',
0x29: 'TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5',
0x2a: 'TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5',
0x2b: 'TLS_KRB5_EXPORT_WITH_RC4_40_MD5',
0x2c: 'TLS_PSK_WITH_NULL_SHA',
0x2d: 'TLS_DHE_PSK_WITH_NULL_SHA',
0x2e: 'TLS_RSA_PSK_WITH_NULL_SHA',
0x2f: 'TLS_RSA_WITH_AES_128_CBC_SHA',
0x30: 'TLS_DH_DSS_WITH_AES_128_CBC_SHA',
0x31: 'TLS_DH_RSA_WITH_AES_128_CBC_SHA',
0x32: 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA',
0x33: 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA',
0x34: 'TLS_DH_anon_WITH_AES_128_CBC_SHA',
0x35: 'TLS_RSA_WITH_AES_256_CBC_SHA',
0x36: 'TLS_DH_DSS_WITH_AES_256_CBC_SHA',
0x37: 'TLS_DH_RSA_WITH_AES_256_CBC_SHA',
0x38: 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA',
0x39: 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA',
0x3a: 'TLS_DH_anon_WITH_AES_256_CBC_SHA',
0x3b: 'TLS_RSA_WITH_NULL_SHA256',
0x3c: 'TLS_RSA_WITH_AES_128_CBC_SHA256',
0x3d: 'TLS_RSA_WITH_AES_256_CBC_SHA256',
0x3e: 'TLS_DH_DSS_WITH_AES_128_CBC_SHA256',
0x3f: 'TLS_DH_RSA_WITH_AES_128_CBC_SHA256',
0x40: 'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256',
0x41: 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA',
0x42: 'TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA',
0x43: 'TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA',
0x44: 'TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA',
0x45: 'TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA',
0x46: 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA',
0x60: 'TLS_RSA_EXPORT1024_WITH_RC4_56_MD5',
0x61: 'TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5',
0x62: 'TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA',
0x63: 'TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA',
0x64: 'TLS_RSA_EXPORT1024_WITH_RC4_56_SHA',
0x65: 'TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA',
0x66: 'TLS_DHE_DSS_WITH_RC4_128_SHA',
0x67: 'TLS_DHE_RSA_WITH_AES_128_CBC_SHA256',
0x68: 'TLS_DH_DSS_WITH_AES_256_CBC_SHA256',
0x69: 'TLS_DH_RSA_WITH_AES_256_CBC_SHA256',
0x6a: 'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256',
0x6b: 'TLS_DHE_RSA_WITH_AES_256_CBC_SHA256',
0x6c: 'TLS_DH_anon_WITH_AES_128_CBC_SHA256',
0x6d: 'TLS_DH_anon_WITH_AES_256_CBC_SHA256',
0x80: 'TLS_GOSTR341094_WITH_28147_CNT_IMIT',
0x81: 'TLS_GOSTR341001_WITH_28147_CNT_IMIT',
0x82: 'TLS_GOSTR341001_WITH_NULL_GOSTR3411',
0x83: 'TLS_GOSTR341094_WITH_NULL_GOSTR3411',
0x84: 'TLS_RSA_WITH_CAMELLIA_256_CBC_SHA',
0x85: 'TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA',
0x86: 'TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA',
0x87: 'TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA',
0x88: 'TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA',
0x89: 'TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA',
0x8a: 'TLS_PSK_WITH_RC4_128_SHA',
0x8b: 'TLS_PSK_WITH_3DES_EDE_CBC_SHA',
0x8c: 'TLS_PSK_WITH_AES_128_CBC_SHA',
0x8d: 'TLS_PSK_WITH_AES_256_CBC_SHA',
0x8e: 'TLS_DHE_PSK_WITH_RC4_128_SHA',
0x8f: 'TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA',
0x90: 'TLS_DHE_PSK_WITH_AES_128_CBC_SHA',
0x91: 'TLS_DHE_PSK_WITH_AES_256_CBC_SHA',
0x92: 'TLS_RSA_PSK_WITH_RC4_128_SHA',
0x93: 'TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA',
0x94: 'TLS_RSA_PSK_WITH_AES_128_CBC_SHA',
0x95: 'TLS_RSA_PSK_WITH_AES_256_CBC_SHA',
0x96: 'TLS_RSA_WITH_SEED_CBC_SHA',
0x97: 'TLS_DH_DSS_WITH_SEED_CBC_SHA',
0x98: 'TLS_DH_RSA_WITH_SEED_CBC_SHA',
0x99: 'TLS_DHE_DSS_WITH_SEED_CBC_SHA',
0x9a: 'TLS_DHE_RSA_WITH_SEED_CBC_SHA',
0x9b: 'TLS_DH_anon_WITH_SEED_CBC_SHA',
0x9c: 'TLS_RSA_WITH_AES_128_GCM_SHA256',
0x9d: 'TLS_RSA_WITH_AES_256_GCM_SHA384',
0x9e: 'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256',
0x9f: 'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384',
0xa0: 'TLS_DH_RSA_WITH_AES_128_GCM_SHA256',
0xa1: 'TLS_DH_RSA_WITH_AES_256_GCM_SHA384',
0xa2: 'TLS_DHE_DSS_WITH_AES_128_GCM_SHA256',
0xa3: 'TLS_DHE_DSS_WITH_AES_256_GCM_SHA384',
0xa4: 'TLS_DH_DSS_WITH_AES_128_GCM_SHA256',
0xa5: 'TLS_DH_DSS_WITH_AES_256_GCM_SHA384',
0xa6: 'TLS_DH_anon_WITH_AES_128_GCM_SHA256',
0xa7: 'TLS_DH_anon_WITH_AES_256_GCM_SHA384',
0xba: 'TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256',
0xbb: 'TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256',
0xbc: 'TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256',
0xbd: 'TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256',
0xbe: 'TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256',
0xbf: 'TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256',
0x00ff: 'TLS_EMPTY_RENEGOTIATION_INFO',
0x5600: 'TLS_EMPTY_RENEGOTIATION_INFO_SCSV',
0x1301: 'TLS_AES_128_GCM_SHA256',
0x1302: 'TLS_AES_256_GCM_SHA384',
0x1303: 'TLS_CHACHA20_POLY1305_SHA256',
0x1304: 'TLS_AES_128_CCM_SHA256',
0x1305: 'TLS_AES_128_CCM_8_SHA256',
0xc001: 'TLS_ECDH_ECDSA_WITH_NULL_SHA',
0xc002: 'TLS_ECDH_ECDSA_WITH_RC4_128_SHA',
0xc003: 'TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA',
0xc004: 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA',
0xc005: 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA',
0xc006: 'TLS_ECDHE_ECDSA_WITH_NULL_SHA',
0xc007: 'TLS_ECDHE_ECDSA_WITH_RC4_128_SHA',
0xc008: 'TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA',
0xc009: 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA',
0xc00a: 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA',
0xc00b: 'TLS_ECDH_RSA_WITH_NULL_SHA',
0xc00c: 'TLS_ECDH_RSA_WITH_RC4_128_SHA',
0xc00d: 'TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA',
0xc00e: 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA',
0xc00f: 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA',
0xc010: 'TLS_ECDHE_RSA_WITH_NULL_SHA',
0xc011: 'TLS_ECDHE_RSA_WITH_RC4_128_SHA',
0xc012: 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA',
0xc013: 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA',
0xc014: 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA',
0xc015: 'TLS_ECDH_anon_WITH_NULL_SHA',
0xc016: 'TLS_ECDH_anon_WITH_RC4_128_SHA',
0xc017: 'TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA',
0xc018: 'TLS_ECDH_anon_WITH_AES_128_CBC_SHA',
0xc019: 'TLS_ECDH_anon_WITH_AES_256_CBC_SHA',
0xc01a: 'TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA',
0xc01b: 'TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA',
0xc01c: 'TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA',
0xc01d: 'TLS_SRP_SHA_WITH_AES_128_CBC_SHA',
0xc01e: 'TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA',
0xc01f: 'TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA',
0xc020: 'TLS_SRP_SHA_WITH_AES_256_CBC_SHA',
0xc021: 'TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA',
0xc022: 'TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA',
0xc023: 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256',
0xc024: 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384',
0xc025: 'TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256',
0xc026: 'TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384',
0xc027: 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256',
0xc028: 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384',
0xc029: 'TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256',
0xc02a: 'TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384',
0xc02b: 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256',
0xc02c: 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',
0xc02d: 'TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256',
0xc02e: 'TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384',
0xc02f: 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
0xc030: 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
0xc031: 'TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256',
0xc032: 'TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384',
0xc033: 'TLS_ECDHE_PSK_WITH_RC4_128_SHA',
0xc034: 'TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA',
0xc035: 'TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA',
0xc036: 'TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA',
0xc037: 'TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256',
0xc038: 'TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384',
0xc039: 'TLS_ECDHE_PSK_WITH_NULL_SHA',
0xc03a: 'TLS_ECDHE_PSK_WITH_NULL_SHA256',
0xc03b: 'TLS_ECDHE_PSK_WITH_NULL_SHA384',
0xc03c: 'TLS_RSA_WITH_ARIA_128_CBC_SHA256',
0xc03d: 'TLS_RSA_WITH_ARIA_256_CBC_SHA384',
0xc03e: 'TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256',
0xc03f: 'TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384',
0xc040: 'TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256',
0xc041: 'TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384',
0xc042: 'TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256',
0xc043: 'TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384',
0xc044: 'TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256',
0xc045: 'TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384',
0xc046: 'TLS_DH_anon_WITH_ARIA_128_CBC_SHA256',
0xc047: 'TLS_DH_anon_WITH_ARIA_256_CBC_SHA384',
0xc048: 'TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256',
0xc049: 'TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384',
0xc04a: 'TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256',
0xc04b: 'TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384',
0xc04c: 'TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256',
0xc04d: 'TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384',
0xc04e: 'TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256',
0xc04f: 'TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384',
0xc050: 'TLS_RSA_WITH_ARIA_128_GCM_SHA256',
0xc051: 'TLS_RSA_WITH_ARIA_256_GCM_SHA384',
0xc052: 'TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256',
0xc053: 'TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384',
0xc054: 'TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256',
0xc055: 'TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384',
0xc056: 'TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256',
0xc057: 'TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384',
0xc058: 'TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256',
0xc059: 'TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384',
0xc05a: 'TLS_DH_anon_WITH_ARIA_128_GCM_SHA256',
0xc05b: 'TLS_DH_anon_WITH_ARIA_256_GCM_SHA384',
0xc05c: 'TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256',
0xc05d: 'TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384',
0xc05e: 'TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256',
0xc05f: 'TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384',
0xc060: 'TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256',
0xc061: 'TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384',
0xc062: 'TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256',
0xc063: 'TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384',
0xc064: 'TLS_PSK_WITH_ARIA_128_CBC_SHA256',
0xc065: 'TLS_PSK_WITH_ARIA_256_CBC_SHA384',
0xc066: 'TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256',
0xc067: 'TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384',
0xc068: 'TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256',
0xc069: 'TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384',
0xc06a: 'TLS_PSK_WITH_ARIA_128_GCM_SHA256',
0xc06b: 'TLS_PSK_WITH_ARIA_256_GCM_SHA384',
0xc06c: 'TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256',
0xc06d: 'TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384',
0xc06e: 'TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256',
0xc06f: 'TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384',
0xc070: 'TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256',
0xc071: 'TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384',
0xc072: 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256',
0xc073: 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384',
0xc074: 'TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256',
0xc075: 'TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384',
0xc076: 'TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256',
0xc077: 'TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384',
0xc078: 'TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256',
0xc079: 'TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384',
0xc07a: 'TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256',
0xc07b: 'TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384',
0xc07c: 'TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256',
0xc07d: 'TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384',
0xc07e: 'TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256',
0xc07f: 'TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384',
0xc080: 'TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256',
0xc081: 'TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384',
0xc082: 'TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256',
0xc083: 'TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384',
0xc084: 'TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256',
0xc085: 'TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384',
0xc086: 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256',
0xc087: 'TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384',
0xc088: 'TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256',
0xc089: 'TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384',
0xc08a: 'TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256',
0xc08b: 'TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384',
0xc08c: 'TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256',
0xc08d: 'TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384',
0xc08e: 'TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256',
0xc08f: 'TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384',
0xc090: 'TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256',
0xc091: 'TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384',
0xc092: 'TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256',
0xc093: 'TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384',
0xc094: 'TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256',
0xc095: 'TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384',
0xc096: 'TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256',
0xc097: 'TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384',
0xc098: 'TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256',
0xc099: 'TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384',
0xc09a: 'TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256',
0xc09b: 'TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384',
0xc09c: 'TLS_RSA_WITH_AES_128_CCM',
0xc09d: 'TLS_RSA_WITH_AES_256_CCM',
0xc09e: 'TLS_DHE_RSA_WITH_AES_128_CCM',
0xc09f: 'TLS_DHE_RSA_WITH_AES_256_CCM',
0xc0a0: 'TLS_RSA_WITH_AES_128_CCM_8',
0xc0a1: 'TLS_RSA_WITH_AES_256_CCM_8',
0xc0a2: 'TLS_DHE_RSA_WITH_AES_128_CCM_8',
0xc0a3: 'TLS_DHE_RSA_WITH_AES_256_CCM_8',
0xc0a4: 'TLS_PSK_WITH_AES_128_CCM',
0xc0a5: 'TLS_PSK_WITH_AES_256_CCM',
0xc0a6: 'TLS_DHE_PSK_WITH_AES_128_CCM',
0xc0a7: 'TLS_DHE_PSK_WITH_AES_256_CCM',
0xc0a8: 'TLS_PSK_WITH_AES_128_CCM_8',
0xc0a9: 'TLS_PSK_WITH_AES_256_CCM_8',
0xc0aa: 'TLS_PSK_DHE_WITH_AES_128_CCM_8',
0xc0ab: 'TLS_PSK_DHE_WITH_AES_256_CCM_8',
0xc0ac: 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM',
0xc0ad: 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM',
0xc0ae: 'TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8',
0xc0af: 'TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8',
0xcc13: 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD',
0xcc14: 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD',
0xcc15: 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD',
0xcca8: 'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256',
0xcca9: 'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256',
0xccaa: 'TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256',
0xccab: 'TLS_PSK_WITH_CHACHA20_POLY1305_SHA256',
0xccac: 'TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256',
0xccad: 'TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256',
0xccae: 'TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256',
0xff00: 'TLS_GOSTR341094_RSA_WITH_28147_CNT_MD5',
0xff01: 'TLS_RSA_WITH_28147_CNT_GOST94',
0xff02: '256',
0xff03: '256',
0xfefe: 'SSL_RSA_FIPS_WITH_DES_CBC_SHA',
0xfeff: 'SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA',
0xfee0: 'SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA',
0xfee1: 'SSL_RSA_FIPS_WITH_DES_CBC_SHA',
// 0x010080: "SSL_CK_RC4_128_WITH_MD5",
// 0x020080: "SSL_CK_RC4_128_EXPORT40_WITH_MD5",
// 0x030080: "SSL_CK_RC2_128_CBC_WITH_MD5",
// 0x040080: "SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5",
// 0x050080: "SSL_CK_IDEA_128_CBC_WITH_MD5",
// 0x060040: "SSL_CK_DES_64_CBC_WITH_MD5",
// 0x060140: "SSL_CK_DES_64_CBC_WITH_SHA",
// 0x0700c0: "SSL_CK_DES_192_EDE3_CBC_WITH_MD5",
// 0x0701c0: "SSL_CK_DES_192_EDE3_CBC_WITH_SHA",
// 0x080080: "SSL_CK_RC4_64_WITH_MD5",
// 0xff0800: "SSL_CK_DES_64_CFB64_WITH_MD5_1",
// 0xff0810: "SSL_CK_NULL",
};
const EXTENSIONS = {
0: 'server_name',
1: 'max_fragment_length',
2: 'client_certificate_url',
3: 'trusted_ca_keys',
4: 'truncated_hmac',
5: 'status_request',
6: 'user_mapping',
7: 'client_authz',
8: 'server_authz',
9: 'cert_type',
10: 'supported_groups',
11: 'ec_point_formats',
12: 'srp',
13: 'signature_algorithms',
14: 'use_srtp',
15: 'heartbeat',
16: 'application_layer_protocol_negotiation',
17: 'status_request_v2',
18: 'signed_certificate_timestamp',
19: 'client_certificate_type',
20: 'server_certificate_type',
21: 'padding',
22: 'encrypt_then_mac',
23: 'extended_master_secret',
24: 'token_binding',
25: 'cached_info',
26: 'tls_lts',
27: 'compress_certificate',
28: 'record_size_limit',
29: 'pwd_protect',
30: 'pwd_clear',
31: 'password_salt',
32: 'ticket_pinning',
33: 'tls_cert_with_extern_psk',
34: 'delegated_credentials',
35: 'session_ticket',
36: 'TLMSP',
37: 'TLMSP_proxying',
38: 'TLMSP_delegate',
39: 'supported_ekt_ciphers',
40: 'Reserved',
41: 'pre_shared_key',
42: 'early_data',
43: 'supported_versions',
44: 'cookie',
45: 'psk_key_exchange_modes',
46: 'Reserved',
47: 'certificate_authorities',
48: 'oid_filters',
49: 'post_handshake_auth',
50: 'signature_algorithms_cert',
51: 'key_share',
52: 'transparency_info',
53: 'connection_id (deprecated)',
54: 'connection_id',
55: 'external_id_hash',
56: 'external_session_id',
57: 'quic_transport_parameters',
58: 'ticket_request',
59: 'dnssec_chain',
1234: 'extensionCustom (boringssl)',
13172: 'extensionNextProtoNeg (boringssl)',
17513: 'extensionApplicationSettings (boringssl)',
65281: 'extensionRenegotiationInfo (boringssl)',
65445: 'extensionQUICTransportParamsLegacy (boringssl)',
30032: 'extensionChannelID (boringssl)',
65535: 'extensionDuplicate (boringssl)',
65037: 'extensionEncryptedClientHello (boringssl)',
64768: 'extensionECHOuterExtensions (boringssl)',
};
class PacketParser {
constructor(buf) {
this.buf = buf;
this.p = {
length: null,
version: null,
clientRandom: null,
sessionId: null,
sessionIdLength: 0,
cipherSuites: [],
cipherSuitesLength: 0,
compressionMethodsLength: 0,
compressionMethods: [],
extensions: [],
parsedExtensions: [],
extensionsLength: 0,
};
this.c = 0; // cursor
const isHandshake = this.readOne() === 0x16;
if (!isHandshake) return;
this.parseAll();
}
readOne() {
return this.buf[this.c++];
}
IntFromNBytes(n) {
let bytes = [];
for (let i = 0; i < n; i++) {
bytes.push(this.readOne());
}
return fromBytes(...bytes);
}
StringFromNBytes(n) {
let bytes = [];
for (let i = 0; i < n; i++) {
bytes.push(this.readOne());
}
const buf = Buffer.from(bytes);
return buf.toString('hex');
}
getCipherName(c) {
if (GREASE.includes(c)) {
return `TLS_GREASE (${c})`;
}
if (CIPHER_SUITES[c]) return `${CIPHER_SUITES[c]} (${c})`;
return `UNKNOWN CIPHER (${c})`;
}
getExtensionName(e) {
if (GREASE.includes(e)) {
return `TLS_GREASE (${e})`;
}
if (EXTENSIONS[e]) return `${EXTENSIONS[e]} (${e})`;
return `UNKNOWN EXTENSION (${e})`;
}
parseAll() {
// TLS Version (outer, unused)
const outerTlsVersion = fromBytes(this.readOne(), this.readOne());
// Total length (not needed)
const totalLength = fromBytes(this.readOne(), this.readOne());
// Handshake type
this.isClientHello = this.readOne() === 0x01;
if (!this.isClientHello) return;
this.p.length = this.IntFromNBytes(3);
this.p.version = this.IntFromNBytes(2);
this.p.clientRandom = this.StringFromNBytes(32);
this.p.sessionIdLength = this.IntFromNBytes(1);
// parse sessionId
if (this.p.sessionIdLength)
this.p.sessionId = this.StringFromNBytes(this.p.sessionIdLength);
// parse cipher suites
this.p.cipherSuitesLength = this.IntFromNBytes(2);
for (let i = 0; i < this.p.cipherSuitesLength; i += 2)
this.p.cipherSuites.push(this.getCipherName(this.IntFromNBytes(2)));
this.p.compressionMethodsLength = this.IntFromNBytes(1);
for (let i = 0; i < this.p.compressionMethodsLength; i++)
this.p.compressionMethods.push(this.IntFromNBytes(1));
this.p.extensionsLength = this.IntFromNBytes(2);
this.parseExtensions();
this.parseExtensionsMore();
}
parseExtensions() {
const end = this.c + this.p.extensionsLength;
while (end > this.c) {
const ext = {};
ext.type = this.IntFromNBytes(2);
ext.len = this.IntFromNBytes(2);
ext.data = [];
for (let i = 0; i < ext.len; i++) ext.data.push(this.readOne());
this.p.extensions.push(ext);
}
}
parseExtensionsMore() {
this.p.extensions.forEach((ext) => {
const next = { name: this.getExtensionName(ext.type) };
// switch (ext.type) {
// case 10:
// // ext.type = 'supported_groups (10)';
// break;
// case 11:
// // ext.type = 'ec_point_formats (11)';
// break;
// case 13:
// // ext.type = 'signature_algorithms (13)';
// break;
// case 16:
// // ext.type = 'application_layer_protocol_negotiation (16)';
// break;
// default:
// // ext.type = `Unknown (${ext.type})`;
// break;
// }
this.p.parsedExtensions.push(next);
});
}
out() {
return {
version: this.p.version,
random: this.p.clientRandom,
sessionId: this.p.sessionId || '',
cipherSuites: this.p.cipherSuites,
compression: this.p.compressionMethods,
extensions: this.p.parsedExtensions,
};
}
}
const PORT = 1337;
const HOST = '127.0.0.1';
const options = {
key: fs.readFileSync('./keys/key.pem'),
cert: fs.readFileSync('./keys/cert.pem'),
};
const tlsServer = tls.createServer(options, async (socket) => {
const t = await tlsChan.read();
socket.on('data', (data) => {
console.log('[REQ]', data.toString().split('\n')[0]);
const body = `<html>
<head>
<title>JA3</TITLE>
</head>
<body>
<pre>${JSON.stringify(t, '\t', 4)}</pre>
</body>
</html>`;
socket.write(`HTTP/1.1 200 OK
Via: HTTP/1.1 proxy_server_name
Server: Apache/1.3
Content-type: text/html, text, plain
Content-length: ${body.length}
${body}`);
});
socket.on('end', function () {});
});
tlsServer.on('error', function (error) {
console.error(error);
tlsServer.destroy();
});
const server = net.createServer(function (socket) {
const proxyStream = new Duplex({
read(size) {},
write(chunk, encoding, callback) {
socket.write(chunk);
callback();
},
});
socket.on('data', (d) => {
proxyStream.push(d);
});
proxyStream.on('data', async (d) => {
const pkg = new PacketParser(d);
if (pkg.isClientHello) setTimeout(() => tlsChan.write(pkg.out()), 0);
});
tlsServer.emit('connection', proxyStream);
});
server.listen(PORT, HOST);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment