Skip to content
Snippets Groups Projects
Commit 03e401a6 authored by Guillaume Valadon's avatar Guillaume Valadon Committed by GitHub
Browse files

Merge pull request #680 from francois-contat/master

Tacacs+ support
parents 72720872 22d493ae
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env python
'''
Copyright (C) 2017 Francois Contat <francois.contat@ssi.gouv.fr>
This program is published under a GPLv2 license
Based on tacacs+ v6 draft https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06
'''
import struct
import hashlib
from scapy.packet import Packet, bind_layers
from scapy.fields import ByteEnumField, ByteField, IntField
from scapy.fields import FieldListField
from scapy.fields import FieldLenField, ConditionalField, StrLenField
from scapy.layers.inet import TCP
from scapy.config import conf
SECRET = 'test'
def obfuscate(pay, secret, session_id, version, seq):
'''
Obfuscation methodology from section 3.7
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-3.7
'''
pad = ''
curr_pad = ''
# pad length must equal the payload to obfuscate.
# pad = {MD5_1 [,MD5_2 [ ... ,MD5_n]]}
while len(pad) < len(pay):
msg = hashlib.md5()
msg.update(struct.pack('!I', session_id))
msg.update(secret)
msg.update(struct.pack('!BB', version, seq))
msg.update(curr_pad)
curr_pad = msg.digest()
pad += curr_pad
# Obf/Unobfuscation via XOR operation between plaintext and pad
new_payload = (struct.pack('B', ord(pad[i]) ^ ord(pay[i])) for i in xrange(len(pay)))
return "".join(new_payload)
TACACSPRIVLEVEL = {15:'Root',
1:'User',
0:'Minimum'}
##########################
# Authentication Packets #
##########################
TACACSVERSION = {1:'Tacacs',
192:'Tacacs+'}
TACACSTYPE = {1:'Authentication',
2:'Authorization',
3:'Accounting'}
TACACSFLAGS = {1:'Unencrypted',
4:'Single Connection'}
TACACSAUTHENACTION = {1:'Login',
2:'Change Pass',
4:'Send Authentication'}
TACACSAUTHENTYPE = {1:'ASCII',
2:'PAP',
3:'CHAP',
4:'ARAP', #Deprecated
5:'MSCHAP',
6:'MSCHAPv2'}
TACACSAUTHENSERVICE = {0:'None',
1:'Login',
2:'Enable',
3:'PPP',
4:'ARAP',
5:'PT',
6:'RCMD',
7:'X25',
8:'NASI',
9:'FwProxy'}
TACACSREPLYPASS = {1:'PASS',
2:'FAIL',
3:'GETDATA',
4:'GETUSER',
5:'GETPASS',
6:'RESTART',
7:'ERROR',
21:'FOLLOW'}
TACACSREPLYFLAGS = {1:'NOECHO'}
TACACSCONTINUEFLAGS = {1:'ABORT'}
class TacacsAuthenticationStart(Packet):
'''
Tacacs authentication start body from section 4.1
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-4.1
'''
name = 'Tacacs Authentication Start Body'
fields_desc = [ByteEnumField('action', 1, TACACSAUTHENACTION),
ByteEnumField('priv_lvl', 1, TACACSPRIVLEVEL),
ByteEnumField('authen_type', 1, TACACSAUTHENTYPE),
ByteEnumField('authen_service', 1, TACACSAUTHENSERVICE),
FieldLenField('user_len', None, fmt='!B', length_of='user'),
FieldLenField('port_len', None, fmt='!B', length_of='port'),
FieldLenField('rem_addr_len', None, fmt='!B', length_of='rem_addr'),
FieldLenField('data_len', None, fmt='!B', length_of='data'),
ConditionalField(StrLenField('user', '', length_from=lambda x: x.user_len),
lambda x: x != ''),
StrLenField('port', '', length_from=lambda x: x.port_len),
StrLenField('rem_addr', '', length_from=lambda x: x.rem_addr_len),
StrLenField('data', '', length_from=lambda x: x.data_len)]
class TacacsAuthenticationReply(Packet):
'''
Tacacs authentication reply body from section 4.2
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-4.2
'''
name = 'Tacacs Authentication Reply Body'
fields_desc = [ByteEnumField('status', 1, TACACSREPLYPASS),
ByteEnumField('flags', 0, TACACSREPLYFLAGS),
FieldLenField('server_msg_len', None, fmt='!H', length_of='server_msg'),
FieldLenField('data_len', None, fmt='!H', length_of='data'),
StrLenField('server_msg', '', length_from=lambda x: x.server_msg_len),
StrLenField('data', '', length_from=lambda x: x.data_len)]
class TacacsAuthenticationContinue(Packet):
'''
Tacacs authentication continue body from section 4.3
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-4.3
'''
name = 'Tacacs Authentication Continue Body'
fields_desc = [FieldLenField('user_msg_len', None, fmt='!H', length_of='user_msg'),
FieldLenField('data_len', None, fmt='!H', length_of='data'),
ByteEnumField('flags', 1, TACACSCONTINUEFLAGS),
StrLenField('user_msg', '', length_from=lambda x: x.user_msg_len),
StrLenField('data', '', length_from=lambda x: x.data_len)]
#########################
# Authorization Packets #
#########################
TACACSAUTHORTYPE = {0:'Not Set',
1:'None',
2:'Kerberos 5',
3:'Line',
4:'Enable',
5:'Local',
6:'Tacacs+',
8:'Guest',
16:'Radius',
17:'Kerberos 4',
32:'RCMD'}
TACACSAUTHORSTATUS = {1:'Pass Add',
2:'Pass repl',
16:'Fail',
17:'Error',
33:'Follow'}
class TacacsAuthorizationRequest(Packet):
'''
Tacacs authorization request body from section 5.1
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-5.1
'''
name = 'Tacacs Authorization Request Body'
fields_desc = [ByteEnumField('authen_method', 0, TACACSAUTHORTYPE),
ByteEnumField('priv_lvl', 1, TACACSPRIVLEVEL),
ByteEnumField('authen_type', 1, TACACSAUTHENTYPE),
ByteEnumField('authen_service', 1, TACACSAUTHENSERVICE),
FieldLenField('user_len', None, fmt='!B', length_of='user'),
FieldLenField('port_len', None, fmt='!B', length_of='port'),
FieldLenField('rem_addr_len', None, fmt='!B', length_of='rem_addr'),
FieldLenField('arg_cnt', None, fmt='!B', count_of='arg_len_list'),
FieldListField('arg_len_list', [], ByteField('', 0),
length_from=lambda pkt: pkt.arg_cnt),
StrLenField('user', '', length_from=lambda x: x.user_len),
StrLenField('port', '', length_from=lambda x: x.port_len),
StrLenField('rem_addr', '', length_from=lambda x: x.rem_addr_len)]
def guess_payload_class(self, pay):
if self.arg_cnt > 0:
return TacacsPacketArguments
return conf.padding_layer
class TacacsAuthorizationReply(Packet):
'''
Tacacs authorization reply body from section 5.2
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-5.2
'''
name = 'Tacacs Authorization Reply Body'
fields_desc = [ByteEnumField('status', 0, TACACSAUTHORSTATUS),
FieldLenField('arg_cnt', None, fmt='!B', count_of='arg_len_list'),
FieldLenField('server_msg_len', None, fmt='!H', length_of='server_msg'),
FieldLenField('data_len', None, fmt='!H', length_of='data'),
FieldListField('arg_len_list', [], ByteField('', 0),
length_from=lambda pkt: pkt.arg_cnt),
StrLenField('server_msg', '', length_from=lambda x: x.server_msg_len),
StrLenField('data', '', length_from=lambda x: x.data_len)]
def guess_payload_class(self, pay):
if self.arg_cnt > 0:
return TacacsPacketArguments
return conf.padding_layer
######################
# Accounting Packets #
######################
TACACSACNTFLAGS = {2:'Start',
4:'Stop',
8:'Watchdog'}
TACACSACNTSTATUS = {1:'Success',
2:'Error',
33:'Follow'}
class TacacsAccountingRequest(Packet):
'''
Tacacs accounting request body from section 6.1
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-6.1
'''
name = 'Tacacs Accounting Request Body'
fields_desc = [ByteEnumField('flags', 0, TACACSACNTFLAGS),
ByteEnumField('authen_method', 0, TACACSAUTHORTYPE),
ByteEnumField('priv_lvl', 1, TACACSPRIVLEVEL),
ByteEnumField('authen_type', 1, TACACSAUTHENTYPE),
ByteEnumField('authen_service', 1, TACACSAUTHENSERVICE),
FieldLenField('user_len', None, fmt='!B', length_of='user'),
FieldLenField('port_len', None, fmt='!B', length_of='port'),
FieldLenField('rem_addr_len', None, fmt='!B', length_of='rem_addr'),
FieldLenField('arg_cnt', None, fmt='!B', count_of='arg_len_list'),
FieldListField('arg_len_list', [], ByteField('', 0),
length_from=lambda pkt: pkt.arg_cnt),
StrLenField('user', '', length_from=lambda x: x.user_len),
StrLenField('port', '', length_from=lambda x: x.port_len),
StrLenField('rem_addr', '', length_from=lambda x: x.rem_addr_len)]
def guess_payload_class(self, pay):
if self.arg_cnt > 0:
return TacacsPacketArguments
return conf.padding_layer
class TacacsAccountingReply(Packet):
'''
Tacacs accounting reply body from section 6.2
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-6.2
'''
name = 'Tacacs Accounting Reply Body'
fields_desc = [FieldLenField('server_msg_len', None, fmt='!H', length_of='server_msg'),
FieldLenField('data_len', None, fmt='!H', length_of='data'),
ByteEnumField('status', None, TACACSACNTSTATUS),
StrLenField('server_msg', '', length_from=lambda x: x.server_msg_len),
StrLenField('data', '', length_from=lambda x: x.data_len)]
class TacacsPacketArguments(Packet):
'''
Class defined to handle the arguments listed at the end of tacacs+
Authorization and Accounting packets.
'''
__slots__ = ['_len']
name = 'Arguments in Tacacs+ packet'
fields_desc = [StrLenField('data', '', length_from=lambda pkt: pkt._len)]
def pre_dissect(self, s):
cur = self.underlayer
i = 0
# Searching the position in layer in order to get its length
while isinstance(cur, TacacsPacketArguments):
cur = cur.underlayer
i += 1
self._len = cur.arg_len_list[i]
return s
def guess_payload_class(self, pay):
cur = self.underlayer
i = 0
# Guessing if Argument packet. Nothing in encapsulated via tacacs+
while isinstance(cur, TacacsPacketArguments):
cur = cur.underlayer
i += 1
if i+1 < cur.arg_cnt:
return TacacsPacketArguments
return conf.padding_layer
class TacacsClientPacket(Packet):
'''
Super class for tacacs packet in order to get them uncrypted
Obfuscation methodology from section 3.7
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-3.7
'''
def post_dissect(self, pay):
if self.flags == 0:
pay = obfuscate(pay, SECRET, self.session_id, self.version, self.seq)
return pay
class TacacsHeader(TacacsClientPacket):
'''
Tacacs Header packet from section 3.8
https://tools.ietf.org/html/draft-ietf-opsawg-tacacs-06#section-3.8
'''
name = 'Tacacs Header'
fields_desc = [ByteEnumField('version', 192, TACACSVERSION),
ByteEnumField('type', 1, TACACSTYPE),
ByteField('seq', 1),
ByteEnumField('flags', 0, TACACSFLAGS),
IntField('session_id', 0),
IntField('length', None)]
def guess_payload_class(self, payload):
# Guessing packet type from type and seq values
# Authentication packet - type 1
if self.type == 1:
if self.seq % 2 == 0:
return TacacsAuthenticationReply
if sum(struct.unpack('bbbb', payload[4:8])) == len(payload[8:]):
return TacacsAuthenticationStart
elif sum(struct.unpack('!hh', payload[:4])) == len(payload[5:]):
return TacacsAuthenticationContinue
# Authorization packet - type 2
if self.type == 2:
if self.seq % 2 == 0:
return TacacsAuthorizationReply
return TacacsAuthorizationRequest
# Accounting packet - type 3
if self.type == 3:
if self.seq % 2 == 0:
return TacacsAccountingReply
return TacacsAccountingRequest
return conf.raw_layer
def post_build(self, p, pay):
# Setting length of packet to obfuscate if not filled by user
if self.length is None and pay:
p = p[:-4] + struct.pack('!I', len(pay))
if self.flags == 0:
pay = obfuscate(pay, SECRET, self.session_id, self.version, self.seq)
return p + pay
return p
def hashret(self):
return struct.pack('I', self.session_id)
def answers(self, other):
return (isinstance(other, TacacsHeader) and
self.seq == other.seq + 1 and
self.type == other.type and
self.session_id == other.session_id)
bind_layers(TCP, TacacsHeader, dport=49)
bind_layers(TCP, TacacsHeader, sport=49)
bind_layers(TacacsHeader, TacacsAuthenticationStart, type=1, dport=49)
bind_layers(TacacsHeader, TacacsAuthenticationReply, type=1, sport=49)
if __name__ == '__main__':
from scapy.main import interact
interact(mydict=globals(), mybanner='tacacs+')
+ Tacacs+ header
= default instanciation
pkt = IP()/TCP(dport=49)/TacacsHeader()
str(pkt) == b'E\x00\x004\x00\x01\x00\x00@\x06|\xc1\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xd0p\x00\x00\xc0\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00'
= default values build
pkt = IP()/TCP(dport=49)/TacacsHeader()
pkt.session_id == 0 and TacacsHeader in pkt
= filled values build
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=5, session_id=165)
str(pkt) == b'E\x00\x004\x00\x01\x00\x00@\x06|\xc1\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xcb\xcb\x00\x00\xc0\x01\x05\x00\x00\x00\x00\xa5\x00\x00\x00\x00'
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x004\x00\x01\x00\x00@\x06|\xc1\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x1c4\x00\x00\xc0\x01\x01\x00\x00Y\xb3\xe3\x00\x00\x00\x00')
pkt.session_id == 5878755
+ Tacacs+ Authentication Start
= default instanciation
pkt = IP()/TCP(dport=49)/TacacsHeader()/TacacsAuthenticationStart()
str(pkt) == b'E\x00\x00<\x00\x01\x00\x00@\x06|\xb9\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xce\xfb\x00\x00\xc0\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x08R\x0f\x9e\xe7\xe0\xd1/\x9c'
= default values build
pkt = IP()/TCP(dport=49)/TacacsHeader()/TacacsAuthenticationStart()
TacacsAuthenticationStart in pkt and pkt.action == 1 and pkt.priv_lvl == 1 and pkt.authen_type == 1 and pkt.authen_service == 1
= filled values build -- SSH connection sample use scapy, secret = test
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=1, flags=0, session_id=2424164486, length=28)/TacacsAuthenticationStart(user_len=5, port_len=4, rem_addr_len=11, data_len=0, user='scapy', port='tty2', rem_addr='172.10.10.1')
str(pkt) == b"E\x00\x00P\x00\x01\x00\x00@\x06|\xa5\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xd4t\x00\x00\xc0\x01\x01\x00\x90}\xd0\x86\x00\x00\x00\x1c\x05\x00POza\xed\xee}\xa5R\xd3Vu+\xbb'\xae\x98\xaa\x1a\x9d\x17=\x90\xd2\x07q"
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00P\x00\x01\x00\x00@\x06|\xa5\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xd5t\x00\x00\xc0\x01\x01\x00\x90}\xd0\x86\x00\x00\x00\x1c\x05\x00POza\xed\xee}\xa5R\xd3Vu+\xbb&\xae\x98\xaa\x1a\x9d\x17=\x90\xd2\x07q')
pkt.user == 'scapy' and pkt.port == 'tty3'
+ Tacacs+ Authentication Reply
= default instanciation
pkt = IP()/TCP(dport=49)/TacacsHeader()/TacacsAuthenticationReply()
str(pkt) == b'E\x00\x00:\x00\x01\x00\x00@\x06|\xbb\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xfd\x9d\x00\x00\xc0\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x06R\x0e\x9f\xe6\xe0\xd1'
= default values build
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=2)/TacacsAuthenticationReply()
TacacsAuthenticationReply in pkt and pkt.status == 1
= filled values build -- SSH connection sample use scapy, secret = test
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=2, flags=0, session_id=2424164486, length=16)/TacacsAuthenticationReply(status=5, flags=1, server_msg_len=10, data_len=0, server_msg='Password: ')
str(pkt) == b'E\x00\x00D\x00\x01\x00\x00@\x06|\xb1\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x0f\x87\x00\x00\xc0\x01\x02\x00\x90}\xd0\x86\x00\x00\x00\x10*\x0c\x1d\xa0\xa2[xE\x0b\t/s\xee\x8b\xd3o'
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00D\x00\x01\x00\x00@\x06|\xb1\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\x0f\x87\x00\x00\xc0\x01\x02\x00\x90}\xd0\x86\x00\x00\x00\x10*\x0c\x1d\xa0\xa2[xE\x0b\t/s\xee\x8b\xd3o')
pkt.server_msg == 'Password: '
+ Tacacs+ Authentication Continue
= default instanciation
pkt = IP()/TCP(dport=49)/TacacsHeader()/TacacsAuthenticationContinue()
str(pkt) == b'E\x00\x009\x00\x01\x00\x00@\x06|\xbc\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xfcp\x00\x00\xc0\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x05S\x0e\x9f\xe6\xe1'
= default values build
pkt = TacacsAuthenticationContinue()
TacacsAuthenticationContinue in pkt and pkt.data == '' and pkt.user_msg == '' and pkt.data_len is None and pkt.user_msg_len is None
= filled values build -- SSH connection sample secret = test, password = pass
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=3, flags=0, session_id=2424164486, length=9)/TacacsAuthenticationContinue(flags=0, user_msg_len=4, data_len=0, user_msg='pass')
str(pkt) == b'E\x00\x00=\x00\x01\x00\x00@\x06|\xb8\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00u\xfa\x00\x00\xc0\x01\x03\x00\x90}\xd0\x86\x00\x00\x00\t\xec8\xc1\x8d\xcc\xec(\xacT'
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00A\x00\x01\x00\x00@\x06|\xb4\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xb5\xfd\x00\x00\xc0\x01\x03\x00\x90}\xd0\x86\x00\x00\x00\r\xec4\xc1\x8d\xcc\xec(\xacT\xd2k&T')
pkt.user_msg == 'password'
+ Tacacs+ Authorization Request
= default instanciation
pkt = IP()/TCP()/TacacsHeader(type=2)/TacacsAuthorizationRequest()
str(pkt) == b'E\x00\x00<\x00\x01\x00\x00@\x06|\xb9\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xcd\xdb\x00\x00\xc0\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x08S\x0f\x9e\xe7\xe0\xd1/\x9c'
= default values build
pkt = IP()/TCP(dport=49)/TacacsHeader(type=2)/TacacsAuthorizationRequest()
TacacsAuthorizationRequest in pkt and pkt.priv_lvl == 1 and pkt.authen_type == 1 and pkt.authen_service == 1
= filled values build -- SSH connection sample secret = test
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=1, type=2 , flags=0, session_id=135252, length=47)/TacacsAuthorizationRequest(authen_method=6, user_len=5, port_len=4, rem_addr_len=11, arg_cnt=2, arg_len_list=[13, 4], user='scapy', port='tty2', rem_addr='172.10.10.1')/TacacsPacketArguments(data='service=shell')/TacacsPacketArguments(data='cmd*')
str(pkt) == b'E\x00\x00c\x00\x01\x00\x00@\x06|\x92\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xb28\x00\x00\xc0\x02\x01\x00\x00\x02\x10T\x00\x00\x00/\xdd\xe0\xe8\xea\xba\xca$Y\xf7\x00\xc2Hh\xed\x03\x1eK84\x10\xb9h\xd7@\x0e\xd5\x13\xf0\xfaA\xfa\xbe;\x01\x82\xecl\xf9\xc6\xa0Z6\x98j\xfd\\9'
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00c\x00\x01\x00\x00@\x06|\x92\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xc2D\x00\x00\xc0\x02\x01\x00R\xf2\x0e\xf4\x00\x00\x00/\xe6\x01\x03 \xd7\xa9\x91\x7fv\xf2\x15-\x88a\xac$\x14\x9f\xc0\xbb\xb8a\xe0\x86e\xf9\xd9\xa2\xc4\xe7\x0bRI\xc8\xdd\x97\xd5\x80\xcf\xce\x81*"\xbc\x15E\x95')
pkt.port == 'tty9'
+ Tacacs+ Authorization Reply
= default instanciation
pkt = IP()/TCP()/TacacsHeader(type=2)/TacacsAuthorizationReply()
str(pkt) == b'E\x00\x00:\x00\x01\x00\x00@\x06|\xbb\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xfc}\x00\x00\xc0\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x06S\x0e\x9f\xe6\xe0\xd1'
= default values build
pkt = TacacsHeader()/TacacsAuthorizationReply()
TacacsAuthorizationReply in pkt and pkt.status == 0 and pkt.arg_cnt is None and pkt.data_len is None
= filled values build -- SSH connection sample secret = test
pkt = Ether()/IP()/TCP(dport=49)/TacacsHeader(seq=2, type=2 , flags=0, session_id=1391595252, length=20)/TacacsAuthorizationReply(status=1, arg_cnt=2, server_msg_len=0, data_len=0, arg_len_list=[11, 1])/TacacsPacketArguments(data='priv-lvl=15')/TacacsPacketArguments(data='a')
str(pkt) == b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00H\x00\x01\x00\x00@\x06|\xad\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00|G\x00\x00\xc0\x02\x02\x00R\xf2\x0e\xf4\x00\x00\x00\x14\xce^Xp~Z\x9b^\xd8Y\xc9"\xf5\xb0&\xe5Ji\xa8\x15'
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00H\x00\x01\x00\x00@\x06|\xad\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00|G\x00\x00\xc0\x02\x02\x00R\xf2\x0e\xf4\x00\x00\x00\x14\xce^Xp~Z\x9b^\xd8Y\xc9"\xf5\xb0&\xe5Ji\xa8\x15')
pkt.status == 1
+ Tacacs+ Accounting Request
= default instanciation
pkt = IP()/TCP()/TacacsHeader(type=3)/TacacsAccountingRequest()
str(pkt) == b'E\x00\x00=\x00\x01\x00\x00@\x06|\xb8\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x00P\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xb3\xd9\x00\x00\xc0\x03\x01\x00\x00\x00\x00\x00\x00\x00\x00\tS\x0e\x9e\xe7\xe1\xd1/\x9c\x19'
= default value build
pkt = IP()/TCP()/TacacsHeader(type=3)/TacacsAccountingRequest()
TacacsAccountingRequest in pkt and pkt.authen_method == 0 and pkt.priv_lvl == 1 and pkt.authen_type == 1
= filled values build -- SSH connection sample secret = test
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=1, type=3 , flags=0, session_id=3059434316, length=67)/TacacsAccountingRequest(flags=2, authen_method=6, priv_lvl=15, authen_type=1, authen_service=1, user_len=5, port_len=4, rem_addr_len=11, arg_cnt=3, arg_len_list=[10, 12, 13], user='scapy', port='tty2', rem_addr='172.10.10.1')/TacacsPacketArguments(data='task_id=24')/TacacsPacketArguments(data='timezone=CET')/TacacsPacketArguments(data='service=shell')
str(pkt) == b'E\x00\x00w\x00\x01\x00\x00@\x06|~\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00sk\x00\x00\xc0\x03\x01\x00\xb6[CL\x00\x00\x00C\x1d\xfb\x81\xd52\xfb\x06\x8b\t\xb9\x0c87\xd3 i\x05\xb5|\x9f\x01l\xbf/\xd3\rc\x0f\nDr\xc0\xc9.\x88@*(S\xfeA\xd4\x19wFj=\xc3\x9f\x00!D\xbe$E\x04\x0e\xe75\x99\xd6\r\x0f\x16\xc7\x1d\xc2'
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x00w\x00\x01\x00\x00@\x06|~\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00|j\x00\x00\xc0\x03\x01\x00\xb6[CL\x00\x00\x00C\x1d\xfb\x81\xd52\xfb\x06\x8b\t\xb9\x0c87\xd3 i\x05\xb5|\x9f\x01l\xb1/\xd3\rc\x0f\nDr\xc0\xc9.\x88@*(S\xfeF\xd5\x19wFj=\xc3\x9f\x00!D\xbe$E\x04\x0e\xe75\x99\xd6\r\x0f\x16\xc7\x1d\xc2')
pkt.rem_addr == '192.10.10.1'
+ Tacacs+ Accounting Reply
= default instanciation
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=2, type=3)/TacacsAccountingReply()
str(pkt) == b'E\x00\x009\x00\x01\x00\x00@\x06|\xbc\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00,\x07\x00\x00\xc0\x03\x02\x00\x00\x00\x00\x00\x00\x00\x00\x05B\xd2A\x8b\x1f'
= default values build
pkt = IP()/TCP(dport=49)/TacacsHeader(seq=2, type=3)/TacacsAccountingReply()
TacacsAccountingReply in pkt and pkt.server_msg == '' and pkt.server_msg_len is None and pkt.status is None
= filled values build -- SSH connection sample secret = test
pkt = Ether()/IP()/TCP(dport=49)/TacacsHeader(seq=2, type=3 , flags=0, session_id=3059434316, length=5)/TacacsAccountingReply(status=1, server_msg_len=0, data_len=0)
str(pkt) == b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x009\x00\x01\x00\x00@\x06|\xbc\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xc5\x7f\x00\x00\xc0\x03\x02\x00\xb6[CL\x00\x00\x00\x05\xf4\x0f\xad,o'
= dissection
pkt = Ether('\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x009\x00\x01\x00\x00@\x06|\xbc\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00\xc5\x7f\x00\x00\xc0\x03\x02\x00\xb6[CL\x00\x00\x00\x05\xf4\x0f\xad,o')
pkt.status == 1
+ Changing secret to foobar
= instanciation
scapy.contrib.tacacs.SECRET = 'foobar'
pkt = Ether()/IP()/TCP(dport=49)/TacacsHeader(session_id=441255181, type=3, seq=2, length=5)/TacacsAccountingReply(status=1, server_msg_len=0, data_len=0)
str(pkt) == b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x009\x00\x01\x00\x00@\x06|\xbc\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00/,\x00\x00\xc0\x03\x02\x00\x1aM\x05\r\x00\x00\x00\x05S)\x9b\xb4\x92'
= dissection
scapy.contrib.tacacs.SECRET = 'foobar'
pkt = Ether(b'\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x08\x00E\x00\x009\x00\x01\x00\x00@\x06|\xbc\x7f\x00\x00\x01\x7f\x00\x00\x01\x001\x001\x00\x00\x00\x00\x00\x00\x00\x00P\x02 \x00/,\x00\x00\xc0\x03\x02\x00\x1aM\x05\r\x00\x00\x00\x05S)\x9b\xb4\x92')
pkt.status == 1
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment