bus*_*ens 12 language-agnostic ssl protocols rfc binary-data
如何从TLS客户端Hello消息中提取服务器名称指示.我很难理解这个关于TLS扩展的非常神秘的RFC 3546,其中定义了SNI.
到目前为止我已经理解的事情:
如果我能找到该长度字节的确切位置,那么提取SNI将非常简单.但是我如何首先到达那个字节?
dlu*_*ist 32
我在sniproxy中做了这个,在Wireshark中检查TLS客户端hello数据包,同时阅读RFC是一个很好的方法.这不是太难,只需要跳过很多变长字段,检查是否有正确的元素类型.
我正在进行我的测试,并且有一个可能有用的带注释的示例数据包:
const unsigned char good_data_2[] = {
// TLS record
0x16, // Content Type: Handshake
0x03, 0x01, // Version: TLS 1.0
0x00, 0x6c, // Length (use for bounds checking)
// Handshake
0x01, // Handshake Type: Client Hello
0x00, 0x00, 0x68, // Length (use for bounds checking)
0x03, 0x03, // Version: TLS 1.2
// Random (32 bytes fixed length)
0xb6, 0xb2, 0x6a, 0xfb, 0x55, 0x5e, 0x03, 0xd5,
0x65, 0xa3, 0x6a, 0xf0, 0x5e, 0xa5, 0x43, 0x02,
0x93, 0xb9, 0x59, 0xa7, 0x54, 0xc3, 0xdd, 0x78,
0x57, 0x58, 0x34, 0xc5, 0x82, 0xfd, 0x53, 0xd1,
0x00, // Session ID Length (skip past this much)
0x00, 0x04, // Cipher Suites Length (skip past this much)
0x00, 0x01, // NULL-MD5
0x00, 0xff, // RENEGOTIATION INFO SCSV
0x01, // Compression Methods Length (skip past this much)
0x00, // NULL
0x00, 0x3b, // Extensions Length (use for bounds checking)
// Extension
0x00, 0x00, // Extension Type: Server Name (check extension type)
0x00, 0x0e, // Length (use for bounds checking)
0x00, 0x0c, // Server Name Indication Length
0x00, // Server Name Type: host_name (check server name type)
0x00, 0x09, // Length (length of your data)
// "localhost" (data your after)
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
// Extension
0x00, 0x0d, // Extension Type: Signature Algorithms (check extension type)
0x00, 0x20, // Length (skip past since this is the wrong extension)
// Data
0x00, 0x1e, 0x06, 0x01, 0x06, 0x02, 0x06, 0x03,
0x05, 0x01, 0x05, 0x02, 0x05, 0x03, 0x04, 0x01,
0x04, 0x02, 0x04, 0x03, 0x03, 0x01, 0x03, 0x02,
0x03, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x03,
// Extension
0x00, 0x0f, // Extension Type: Heart Beat (check extension type)
0x00, 0x01, // Length (skip past since this is the wrong extension)
0x01 // Mode: Peer allows to send requests
};
Run Code Online (Sandbox Code Playgroud)
小智 6
使用WireShark并通过添加过滤器仅捕获TLS(SSL)包tcp port 443.然后找到"客户端Hello"消息.您可以在下面看到其原始数据.
展开
,你会看到.Handshake包中的服务器名称未加密.Secure Socket Layer->TLSv1.2 Record Layer: Handshake Protocol: Client Hello->...Extension: server_name->Server Name Indication extension
http://i.stack.imgur.com/qt0gu.png
对于任何感兴趣的人,这是 C/C++ 代码的暂定版本。到目前为止它已经奏效了。该函数返回服务器名称在包含客户端问候的字节数组中的位置以及参数中名称的长度len。
char *get_TLS_SNI(unsigned char *bytes, int* len)
{
unsigned char *curr;
unsigned char sidlen = bytes[43];
curr = bytes + 1 + 43 + sidlen;
unsigned short cslen = ntohs(*(unsigned short*)curr);
curr += 2 + cslen;
unsigned char cmplen = *curr;
curr += 1 + cmplen;
unsigned char *maxchar = curr + 2 + ntohs(*(unsigned short*)curr);
curr += 2;
unsigned short ext_type = 1;
unsigned short ext_len;
while(curr < maxchar && ext_type != 0)
{
ext_type = ntohs(*(unsigned short*)curr);
curr += 2;
ext_len = ntohs(*(unsigned short*)curr);
curr += 2;
if(ext_type == 0)
{
curr += 3;
unsigned short namelen = ntohs(*(unsigned short*)curr);
curr += 2;
*len = namelen;
return (char*)curr;
}
else curr += ext_len;
}
if (curr != maxchar) throw std::exception("incomplete SSL Client Hello");
return NULL; //SNI was not present
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14566 次 |
| 最近记录: |