Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
scapy
Manage
Activity
Members
Plan
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CodeLinaro
public-release-test-restored
platform
external
scapy
Commits
22d493ae
Commit
22d493ae
authored
7 years ago
by
Francois Contat
Browse files
Options
Downloads
Patches
Plain Diff
Tacacs+ support
parent
a28da9f7
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
scapy/contrib/tacacs.py
+432
-0
432 additions, 0 deletions
scapy/contrib/tacacs.py
scapy/contrib/tacacs.uts
+190
-0
190 additions, 0 deletions
scapy/contrib/tacacs.uts
with
622 additions
and
0 deletions
scapy/contrib/tacacs.py
0 → 100755
+
432
−
0
View file @
22d493ae
#!/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+
'
)
This diff is collapsed.
Click to expand it.
scapy/contrib/tacacs.uts
0 → 100644
+
190
−
0
View file @
22d493ae
+ 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
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment