Unable to trace HTTP2 stream when decrypting tls in tls traffic
Because this is my first time using the Ask system, I don't know why images cannot be uploaded. I have uploaded this document here, you can choose to read it here
target:
Hi, everyone. I'm trying to decrypt Trojan traffic using wireshark, Trojan's encryption is two layers of TLS,i.e. TLS in TLS.
trouble:
Unable to trace HTTP2 stream Here is an example of a traffic package for accessing Google using Trojan proxy. Attempt to track the following stream:tcp.stream eq 31 and http2.streamid eq 0
Attempt to track the following stream:tcp.stream eq 31 and http2.streamid eq 1is empty, but according to the parse tree in the figure below, it can parse normal traffic. Does this indicate that the decryption was normal, but the stream information was lost?
code implementation
general idea:
The following is the key implementation process, ignoring some code. For detailed implementation, please refer to https://github.com/SIGPET-SEU/Wiresha...
- proto_register_trojan()
void proto_register_trojan(void) { proto_trojan = proto_register_protocol( "Trojan Protocol", /* name */ "Trojan", /* short_name */ "trojan" /* filter_name */ ); trojan_handle = register_dissector("trojan", dissect_trojan, proto_trojan); }
- proto_reg_handoff_trojan() Disconnect the first layer of tls from HTTP2, so that wireshark can call the trojan dissector after the first layer of tls is decrypted. (dissector_add_string("tls.alpn", "h2", trojan_handle))
void proto_reg_handoff_trojan(void) { dissector_add_uint("tls.port", TROJAN_TLS_PORT, trojan_handle); // Disconnect the first layer of tls from HTTP2, so that wireshark can call the trojan dissector after the first layer of tls is decrypted dissector_add_string("tls.alpn", "h2", trojan_handle); heur_dissector_add("tls", dissect_trojan_heur_tls, "Trojan Over Tls", "trojan_over_tls", proto_trojan, HEURISTIC_ENABLE); }
- dissect_trojan() The following code first checks whether the TLS packet header matches the content of the current TVB. If it matches, then the current content is TLS content and a second TLS decryption is performed.
- Before call_tls_ handle, because the two tls decryption keys are different, a new tls session needs to be created to force Wireshark to use the new key. Wireshark uses quintuples (src_ip, src_port, dst_ip, dst_port, pinfo ->ptype) internally to find previous session information, so the port type is forcibly changed here to force Wireshark to establish a new session. (pinfo->ptype = PT_NONE)
- Another important thing is that we cut off the connection between TLS and HTTP2 when registering the Trojan protocol, so Wireshark will enter Trojan dissector instead of HTTP2 after decrypting the first layer TLS. But after decrypting the second layer TLS, HTTP2 is still needed for parsing, so we will reconstruct the connection here. (dissector_add_string("tls.alpn", "h2", h2_handle))
- The tls code implements a data reassembly mechanism, so we do not consider data reassembly here
bool is_trojan_response(tvbuff_t* tvb) { // Match the information of tls header return tvb_find_TLS_signature(tvb) == 0 ? true : false; } static int dissect_trojan(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree _U_, void* data _U_) { if (is_trojan_response(tvb)) { // save pinfo save_port_type = pinfo->ptype; save_can_desegment = pinfo->can_desegment; pinfo->ptype = PT_NONE; pinfo->can_desegment = pinfo->saved_can_desegment; col_set_str(pinfo->cinfo, COL_INFO, "Trojan Response"); ti = proto_tree_add_item(tree, proto_trojan, tvb, 0, -1, ENC_NA); trojan_tree = proto_item_add_subtree(ti, ett_trojan); proto_tree_add_item(trojan_tree, hf_trojan_tunnel_data, tvb, 0, tvb_reported_length(tvb), ENC_BIG_ENDIAN); next_tvb = tvb_new_subset_remaining(tvb, 0); dissector_add_string("tls.alpn ...