Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tolerate malformed server_name TLS extensions #4001

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

evverx
Copy link
Contributor

@evverx evverx commented May 2, 2023

The servernames packet list field can contain "Raw" instances when server_name extenstions are malformed. The "i2repr" method doesn't expect that and ends up throwing exceptions when it can't find the "servername" attribute. This patch addresses that by removing the ServerListField class and relying on PacketListField doing the right thing. Another option would be to use something like

[getattr(p, "servername", p) for p in x]

in the "ServerListField.i2repr" method but I think full server names along with their types and lengths are more helpful.

Fixes:

  File "scapy/packet.py", line 563, in __repr__
    val = f.i2repr(self, fval)
          ^^^^^^^^^^^^^^^^^^^^
  File "scapy/layers/tls/extensions.py", line 180, in i2repr
    res = [p.servername for p in x]
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "scapy/layers/tls/extensions.py", line 180, in <listcomp>
    res = [p.servername for p in x]
           ^^^^^^^^^^^^
  File "scapy/packet.py", line 467, in __getattr__
    return self.payload.__getattr__(attr)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "scapy/packet.py", line 465, in __getattr__
    fld, v = self.getfield_and_val(attr)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "scapy/packet.py", line 1788, in getfield_and_val
    raise AttributeError(attr)
AttributeError: servername

The servernames packet list field can contain "Raw" instances when
server_name extenstions are malformed. The "i2repr" method doesn't
expect that and ends up throwing exceptions when it can't find the
"servername" attribute. This patch addresses that by removing the
ServerListField class and relying on PacketListField doing the right
thing. Another option would be to use something like
```
[getattr(p, "servername", p) for p in x]
```
in the "ServerListField.i2repr" method but I think full server names
along with their types and lengths are more helpful.

Fixes:
```
  File "scapy/packet.py", line 563, in __repr__
    val = f.i2repr(self, fval)
          ^^^^^^^^^^^^^^^^^^^^
  File "scapy/layers/tls/extensions.py", line 180, in i2repr
    res = [p.servername for p in x]
          ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "scapy/layers/tls/extensions.py", line 180, in <listcomp>
    res = [p.servername for p in x]
           ^^^^^^^^^^^^
  File "scapy/packet.py", line 467, in __getattr__
    return self.payload.__getattr__(attr)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "scapy/packet.py", line 465, in __getattr__
    fld, v = self.getfield_and_val(attr)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "scapy/packet.py", line 1788, in getfield_and_val
    raise AttributeError(attr)
AttributeError: servername
```
@codecov
Copy link

codecov bot commented May 2, 2023

Codecov Report

Merging #4001 (f9f2b19) into master (047be32) will decrease coverage by 0.01%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##           master    #4001      +/-   ##
==========================================
- Coverage   81.93%   81.92%   -0.01%     
==========================================
  Files         328      328              
  Lines       75404    75400       -4     
==========================================
- Hits        61783    61773      -10     
- Misses      13621    13627       +6     
Impacted Files Coverage Δ
scapy/layers/tls/extensions.py 84.22% <ø> (+0.42%) ⬆️

... and 8 files with indirect coverage changes

@@ -175,12 +175,6 @@ def guess_payload_class(self, p):
return Padding


class ServerListField(PacketListField):
def i2repr(self, pkt, x):
res = [p.servername for p in x]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like res = [getattr(p, "servername", p) for p in x] should work too (and it would be more in line with the other extensions). Looking at its base class it seems the idea is to always show names only:

the final field is showed as a 1-line list rather than as lots of packets

@evverx evverx marked this pull request as draft May 2, 2023 21:44
@evverx
Copy link
Contributor Author

evverx commented May 18, 2023

TLS_Ext_PrettyPacketList doesn't seem to be compatible with Raw instances conceptually. I'll try to figure out how to make them prettier. This PR just dumps bytes and calls it a day :-)

@gpotter2 gpotter2 added the tls label Oct 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants