Skip to content

Commit

Permalink
HTTPS server, better Automaton.spawn
Browse files Browse the repository at this point in the history
  • Loading branch information
gpotter2 committed Sep 2, 2024
1 parent a5dab9e commit 52f1a1f
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 43 deletions.
2 changes: 1 addition & 1 deletion doc/scapy/layers/smb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ Let's re-do the initial example programmatically, by turning off the CLI mode. O
('Users', 'DISKTREE', '')]
>>> cli.use('c$')
>>> cli.cd(r'Program Files\Microsoft')
>>> >>> names = [x[0] for x in cli.ls()]
>>> names = [x[0] for x in cli.ls()]
>>> names
['.', '..', 'EdgeUpdater']
Expand Down
39 changes: 28 additions & 11 deletions scapy/automaton.py
Original file line number Diff line number Diff line change
Expand Up @@ -1000,29 +1000,46 @@ def _run() -> None:
# Wait for clients forever
try:
while True:
clientsocket, address = ssock.accept()
if kwargs.get("verb", True):
print(conf.color_theme.gold(
"\u2503 Connection received from %s" % repr(address)
))
# Start atmt class with socket
sock = cls.socketcls(clientsocket, cls.pkt_cls)
atmt_server = cls(
sock=sock,
iface=iface, **kwargs
)
try:
clientsocket, address = ssock.accept()
if kwargs.get("verb", True):
print(conf.color_theme.gold(
"\u2503 Connection received from %s" % repr(address)
))
# Start atmt class with socket
if cls.socketcls is not None:
sock = cls.socketcls(clientsocket, cls.pkt_cls)
else:
sock = clientsocket
atmt_server = cls(
sock=sock,
iface=iface, **kwargs
)
except OSError:
if kwargs.get("verb", True):
print("X Connection closed.")
if kwargs.get("debug", 0) > 0:
traceback.print_exc()
continue
clients.append((atmt_server, clientsocket))
# start atmt
atmt_server.runbg()
# housekeeping
for atmt, clientsocket in clients:
if not atmt.isrunning():
atmt.destroy()
except KeyboardInterrupt:
print("X Exiting.")
ssock.shutdown(socket.SHUT_RDWR)
except OSError:
print("X Server closed.")
if kwargs.get("debug", 0) > 0:
traceback.print_exc()
finally:
for atmt, clientsocket in clients:
try:
atmt.forcestop(wait=False)
atmt.destroy()
except Exception:
pass
try:
Expand Down
52 changes: 50 additions & 2 deletions scapy/layers/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -990,15 +990,15 @@ class HTTP_Server(Automaton):
def __init__(
self,
mech=HTTP_AUTH_MECHS.NONE,
ssp=None,
verb=True,
ssp=None,
*args,
**kwargs,
):
self.verb = verb
if "sock" not in kwargs:
raise ValueError(
"HTTP_Server cannot be started directly ! Use SMB_Server.spawn"
"HTTP_Server cannot be started directly ! Use HTTP_Server.spawn"
)
self.ssp = ssp
self.authmethod = mech.value
Expand Down Expand Up @@ -1197,3 +1197,51 @@ def answer(self, pkt):
) / (
"<!doctype html><html><body><h1>404 - Not Found</h1></body></html>"
)


class HTTPS_Server(HTTP_Server):
"""
HTTPS server automaton
This has the same arguments and attributes as HTTP_Server, with the addition of:
:param sslcontext: an optional SSLContext object.
If used, cert and key are ignored.
:param cert: path to the certificate
:param key: path to the key
"""

socketcls = None

def __init__(
self,
mech=HTTP_AUTH_MECHS.NONE,
verb=True,
cert=None,
key=None,
sslcontext=None,
ssp=None,
*args,
**kwargs,
):
if "sock" not in kwargs:
raise ValueError(
"HTTPS_Server cannot be started directly ! Use HTTPS_Server.spawn"
)
# wrap socket in SSL
if sslcontext is None:
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(cert, key)
else:
context = sslcontext
kwargs["sock"] = SSLStreamSocket(
context.wrap_socket(kwargs["sock"], server_side=True),
self.pkt_cls,
)
super(HTTPS_Server, self).__init__(
mech=mech,
verb=verb,
ssp=ssp,
*args,
**kwargs,
)
4 changes: 3 additions & 1 deletion scapy/layers/kerberos.py
Original file line number Diff line number Diff line change
Expand Up @@ -1790,7 +1790,9 @@ def m2i(self, pkt, s):
# 24: KDC_ERR_PREAUTH_FAILED
# 25: KDC_ERR_PREAUTH_REQUIRED
return MethodData(val[0].val, _underlayer=pkt), val[1]
elif pkt.errorCode.val in [13, 18, 29, 41, 60]:
elif pkt.errorCode.val in [6, 7, 13, 18, 29, 41, 60]:
# 6: KDC_ERR_C_PRINCIPAL_UNKNOWN
# 7: KDC_ERR_S_PRINCIPAL_UNKNOWN
# 13: KDC_ERR_BADOPTION
# 18: KDC_ERR_CLIENT_REVOKED
# 29: KDC_ERR_SVC_UNAVAILABLE
Expand Down
8 changes: 7 additions & 1 deletion scapy/layers/ntlm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1674,8 +1674,14 @@ def GSS_Accept_sec_context(self, Context: CONTEXT, val=None):
# [MS-NLMP] sect 3.2.5.1.2
KeyExchangeKey = SessionBaseKey # Only true for NTLMv2
if auth_tok.NegotiateFlags.NEGOTIATE_KEY_EXCH:
if not auth_tok.EncryptedRandomSessionKeyLen:
# No EncryptedRandomSessionKey. libcurl for instance
# hmm. this looks bad
EncryptedRandomSessionKey = b"\x00" * 16
else:
EncryptedRandomSessionKey = auth_tok.EncryptedRandomSessionKey
ExportedSessionKey = RC4K(
KeyExchangeKey, auth_tok.EncryptedRandomSessionKey
KeyExchangeKey, EncryptedRandomSessionKey
)
else:
ExportedSessionKey = KeyExchangeKey
Expand Down
2 changes: 1 addition & 1 deletion scapy/themes.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ def __getattr__(self, attr: str) -> _ColorFormatterType:
styler = super(LatexTheme, self).__getattr__(attr)
return cast(
_ColorFormatterType,
lambda x, *args, **kwargs: styler(tex_escape(x), *args, **kwargs),
lambda x, *args, **kwargs: styler(tex_escape(str(x)), *args, **kwargs),
)


Expand Down
9 changes: 4 additions & 5 deletions scapy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@
from itertools import zip_longest
from uuid import UUID

import array
import argparse
import array
import base64
import collections
import decimal
import difflib
Expand Down Expand Up @@ -44,8 +45,6 @@
orb,
plain_str,
chb,
bytes_base64,
base64_bytes,
hex_bytes,
bytes_encode,
)
Expand Down Expand Up @@ -1229,15 +1228,15 @@ def __repr__(self):
def export_object(obj):
# type: (Any) -> None
import zlib
print(bytes_base64(zlib.compress(pickle.dumps(obj, 2), 9)))
print(base64.b64encode(zlib.compress(pickle.dumps(obj, 2), 9)).decode())


def import_object(obj=None):
# type: (Optional[str]) -> Any
import zlib
if obj is None:
obj = sys.stdin.read()
return pickle.loads(zlib.decompress(base64_bytes(obj.strip()))) # noqa: E501
return pickle.loads(zlib.decompress(base64.b64decode(obj.strip())))


def save_object(fname, obj):
Expand Down
42 changes: 21 additions & 21 deletions test/scapy/layers/tls/tls.uts

Large diffs are not rendered by default.

0 comments on commit 52f1a1f

Please sign in to comment.