Click on our Sponsors to help Support SunWorld
Wizard's Guide to Security by Carole Fennelly

Summertime potluck

This mixed bag of goodies includes additional tidbits on sendmail and chroot

SunWorld
August  1999
[Next story]
[Table of Contents]
[Search]
Subscribe to SunWorld, it's free!

Abstract
In this month's column, Carole ties up some loose ends left over from previous columns on sendmail and chroot (padded cells). The checkcompat() routine is discussed, as well as a method for defeating a possible exploit against chroot. As an added bonus, some review of the Black Hat briefings and Defcon. (3,000 words)


Mail this
article to
a friend
Last month's column on social engineering generated quite a bit of feedback and discussion. Thanks to everyone who wrote (see messages from Doug Pardue and Garrett Roy). It's amazing how many people wanted the profanity-laced response to chain letters! If at any time you sent me mail and I did not respond, please send it again. I try to answer everything, but sometimes I miss a few.

This month's installment is in the spirit of that traditional part of the dog days of summer, the potluck supper. I'm using this month's column to tie up some loose ends with sendmail and chroot, based on reader feedback. Also, I regret that I could not attend the Black Hat Briefings and Defcon; to get the scoop, I asked some technical friends for feedback to decide if I should go next year. There has already been a tremendous amount of press coverage, but reporters usually cannot evaluate the technical value of a talk.

Sendmail leftovers
At this point, I don't intend to write an article entitled "Sendmail, Part 4," but I would like to devote a few paragraphs to sendmail's checkcompat() routine. The checkcompat() routine is called at a place where both the sender and recipient data are available before the mail is delivered. On a firewall, it can be used to strip out all internal headers from a mail message before sending the mail. An example of this can be found in Sendmail, 2nd edition, by Bryan Costales, on page 293 (section 20.2.5). The checkcompat() routine can be used in other ways as well. To demonstrate, I will provide two examples. The first logs the sender, recipient, and subject of each mail message. The second inserts a text string into each mail header. Note that these are compile-time modifications, so it's not convenient if you plan on changing them often.

checkcompat()
The checkcompat() routine is an internal function in the sendmail source code and requires some C programming expertise to use. Any local modifications are compiled into sendmail and cannot be changed without recompiling. If you use it, you will need to keep a copy of your routine (perhaps where you keep your local *.mc files) so that you can integrate it into subsequent sendmail releases. You may also need to modify your routine with subsequent releases. This all sounds like an awful lot of work -- you may be wondering why it would be worth the bother. Well, it's a very powerful way to make sendmail perform special operations before actually delivering mail. For more background on how it works, I encourage you to read Chapter 20 in the Sendmail book. I'll just demonstrate its use. The examples given here were tested on sendmail 8.9.3.

Logging sender/recipient/subject
A reader sent me mail asking how to have sendmail log the subject of each message, as well as the sender and recipient. I failed to come up with a clean conventional solution (doesn't mean there isn't one -- just that I didn't find it), but discovered that it could be done very effectively using checkcompat():

#ifdef FIREWALL
#define LOOP_CHECK "X-Loop-Check"
#endif
int
checkcompat(to, e)
        register ADDRESS *to;
        register ENVELOPE *e;
{
#ifdef FIREWALL
        int cnt;
        HDR *h;
#endif
# ifdef lint
        if (to == NULL)
                to++;
# endif /* lint */

        if (tTd(49, 1))
                printf("checkcompat(to=%s, from=%s)\n",
                        to->q_paddr, e->e_from.q_paddr);

        /* this is a locally submitted message  ? */

#ifdef FIREWALL

        if (hvalue(LOOP_CHECK,e->e_header) != NULL) {
                /* Been here, done this */
                return(EX_OK);
        }

        /* Add a loop back check header */

        addheader(LOOP_CHECK, "", &e->e_header);

        for (cnt = 0, h = e->e_header; h != NULL; h = h->h_link) {

                /* If not a subject, then skip it */
                if (strcasecmp(h->h_field,"subject") != 0)
                        continue;

                if (h->h_value)
                        sm_syslog(LOG_INFO, e->e_id,
                                "to=%s,from=%s,Subject: '%s'",
                                to->q_paddr, e->e_from.q_paddr,h->h_value);
        }
#endif

        return (EX_OK);
}

Below is sample output from the log file that shows the subject as "New Test." You can take this as input to a script, which can then render the data into a more readable form:

Jul 18 14:02:02 rahl sendmail[1990]: OAA01990: from=klein, size=56, class=0,
pri=30056, nrcpts=1, msgid=<199907181802.OAA01990@rahl.wkeys.com>,
relay=root@localhost
Jul 18 14:02:02 rahl sendmail[1992]: OAA01990: to=klein,from=klein,Subject:
'New Test'
Jul 18 14:02:02 rahl sendmail[1992]: OAA01990: to=klein, ctladdr=klein
(1002/10), delay=00:00:00, xdelay=00:00:00, mailer=local, stat=Sent

Inserting special text
The managers of many sites want the ability to insert text that makes some statement about the site into every mail header. It can be done using checkcompat(), provided that you don't need to change your message very often. Why would you want to put text in your mail header at all? Well, you may want some sort of disclaimer statement, or some other legalese. Or, you may want to advertise your Web page. It shouldn't be very lengthy, and it should be something that is appropriate for all users (including the CEO).

#ifdef FIREWALL
char *copyright[] = {
"This material is property of the XYZ Corporation. Any misuse or",
"unauthorized redistribution of this e-mail is a violation of",
"state and/or federal laws. This notice must appear in all e-mails",
"and may not be removed without prior written consent of XYZ",
"Corporation"
};
int size=(sizeof(copyright)/sizeof(char *));
#define LOOP_CHECK "X-Loop-Check"
#endif

int
checkcompat(to, e)
        register ADDRESS *to;
        register ENVELOPE *e;
{
#ifdef FIREWALL
        int cnt;
        HDR *h;
#endif
# ifdef lint
        if (to == NULL)
                to++;
# endif /* lint */

        if (tTd(49, 1))
                printf("checkcompat(to=%s, from=%s)\n",
                        to->q_paddr, e->e_from.q_paddr);

        /* this is a locally submitted message  ? */

#ifdef FIREWALL

        if (hvalue(LOOP_CHECK,e->e_header) != NULL) {
                /* Been here, done this */
                return(EX_OK);
        }

        /* Add a loop back check header */

        addheader(LOOP_CHECK, "", &e->e_header);
        for (cnt = size - 1; cnt >= 0; cnt--)
                addheader("X-Ownership",copyright[cnt],&e->e_header);

#endif

        return (EX_OK);
}

This is what the mail message would look like:

>From klein Thu Jul 22 21:39 EDT 1999
Received: (from root@localhost)
        by rahl.wkeys.com (8.9.3/8.9.3) id VAA06567
        for klein; Thu, 22 Jul 1999 21:39:16 -0400 (EDT)
Date: Thu, 22 Jul 1999 21:39:16 -0400 (EDT)
From: Jonathan Klein <klein>
Message-Id: <199907230139.VAA06567@rahl.wkeys.com>
To: klein
Subject: Test Messages
X-Ownership: This material is property of the XYZ Corporation. Any misuse or
X-Ownership: unauthorized redistribution of this e-mail is a violation of
X-Ownership: state and/or federal laws. This notice must appear in all
e-mails
X-Ownership: and may not be removed without prior written consent of XYZ
X-Ownership: Corporation
Content-Type: text
Content-Length: 5
Status: RO

Test


Advertisements

Padded cell leftovers
In previous columns, I wrote about using the chroot() system call to create a padded cell for an application. It has been stated, quite correctly, that it is possible to defeat chroot() if there is an exploitable setuid program in the padded cell. (See Simon Burr's guide to breaking out of a chroot() jail at http://www.bpfh.net/simes/computing/chroot-break.html for an example.) It seems that chroot() retains internal information about its original parent directory.

In the the Simon Burr example above, the program opens a directory to the current directory, chroot's into a directory called temp, and then uses fchdir and chdir to follow the parent path back up the line to get to the real root, thus breaking the padded cell.

In an effort to defeat this program, my partner, Jon Klein, came up with a method that keeps chroot from having a valid link to the real system. The way this is done is a bit of a hack -- essentially you are creating a broken filesystem on top of the filesystems that contain your padded cells. This filesystem contains a loop; as a result, it must be remade on every reboot, because fsck will not be happy with the corrupted parent loop and will try to fix it. The script to recreate the top-level filesystem follows. It is recommended that the chroot script be run after only all the mounts are complete. In my implementation, I added the chroot script to S01MOUNTFSYS in /etc/rc2.d after the mountall:

...code deleted
# Added by JIK. Do not erase. This is needed for the padded cells

/sbin/chroot-help /dev/rdsk/c0t1d0s5 /dev/dsk/c0t1d0s5 /var/cells
/sbin/mount /dev/dsk/c0t1d0s5 /var/cells

/sbin/mount /var/cells/cell_top/sendmail
/sbin/mount /var/cells/cell_top/extra
/sbin/mount /var/cells/cell_top/extra2

# nothing changed below..just left in a place reference CF

# The following counts the number of filesystems with quotas enabled
NQUOTA=`cut -f 4 /etc/mnttab | egrep -c "^quota|,quota"`

if [ $NQUOTA -gt 0 ]
then
        echo "Checking UFS quotas: \c"
        /usr/sbin/quotacheck -a -p
        echo "done."
        /usr/sbin/quotaon -a
fi

I put a commented line in /etc/vfstab to keep a marker for the minifilesystem I created, and allowed the mounts for the filesystems that rely on the broken filesystem (the padded cell filesystems) to fail. After the chroot script, make sure you add mounts for the padded cell file systems so that they get online. Before you use the script, make a small filesystem (about one megabyte will do). The script creates a new filesystem and mounts it. Then, it makes directories cell_top, cell_top/tmp, and cell_top/tmp/loser, and whatever other filesystems you want under cell_top, in this case sendmail extra and extra2.

Edit the script to create whatever other directories you need. The most important thing is to create cell_top and cell_top/tmp/loser, and to put all the directories for the padded cells under cell_top. In addition, because the cell_top filesystem is recreated each time the system is booted, you should not put anything in this filesystem that you want to survive a reboot. As separate filesystems, the padded cell filesystems retain their data and are mounted after the script is run.

After the directories are created, we locate the inode numbers for both cell_top and cell_top/tmp/loser. Now comes the fun part. The script uses fsdb (filesystem debugger -- a favorite of old timers) to edit the filesystem and do the following:

At this point, mount all the other filesystems that are to go under cell_top. Essentially, what you've done is create a parent loop between cell_top and cell_top/tmp/loser. When you try to run the breakout program, it will go into an infinite loop. You should also try to avoid passing through the parent directory in cell_top, as it causes things like sh and pwd to act oddly. Use the absolute path if you need to pass up through cell_top. You can traverse downward through cell_top with no adverse problems.

Lastly, here is the chroot filesystem script:

!/sbin/sh
# Create a broken filesystem to prevent chroot breakout
#
if [ "$1" = "" -o "$2" = ""  -o "$3" = "" ]
then
        echo "Usage: chroot-help <char device> <block device> <mountpoint>"
        exit 1
fi

# Make sure it is unmounted

/sbin/umount $2

# Make file system
/usr/sbin/newfs $2 <<END
y
END

if [ $? -ne 0 ]
then
        echo "Could not make file system"
        exit 2
fi

# Mount file system

/usr/sbin/mount $2 $3
if [ $? -ne 0 ]
then
        echo "Cannot mount file system"
        exit 3
fi
cd $3

# Make top level directories

/bin/mkdir -p cell_top/tmp/loser
/bin/mkdir -p cell_top/sendmail
/bin/mkdir -p cell_top/extra
/bin/mkdir -p cell_top/extra2

# Get inode numbers

top=`ls -id . | sed -e 's/^ *//' | cut -f1 -d" "`
c=`ls -id top/tmp/loser | sed -e 's/^ *//' | cut -f1 -d" "`
echo $top $parent $c

# Unmount directories

cd /
/usr/sbin/umount $2

# Create corrupted directory parent
/usr/sbin/fsdb -o w $1 << END
2:inode
:ln=-1
0t$c:inode
:ln=+1
2:inode
:cd cell_top
1:dir=0t$c
:quit
END

# We are done

Mail regarding chroot
I ran this method past Simon to see what he thought of it. His comments follow:

"The method to defeat the break out is interesting and quite nice. However, I really doubt that I'd be allowed to install it on a production server. Sysadmins tend to get a little uneasy when people start to mess with the filesystems at that level. (They still shudder when they remember the fun they had when a system changed ".." to ".," (note the comma) on a certain directory for some strange unknown reason occasionally.) Their argument would be that the risk of someone getting root within a chroot() jail is less than the risk of something going wrong with the filesystem hack. In a well-designed system, this should be the case. Unfortunately, wu-ftpd is not well designed (the internal structure and code is absolutely horrendous -- I'm amazed that there haven't been more problems with it). There is another problem. If the attacker has root access, then there is nothing to stop him or her from doing an lstat(), using mknod() to create a device entry, and then looking at the device directly to fix the problem. It does require a high level of knowledge to do this, however."

My response to Simon's comments are this:

I agree that hacking the filesystem inode is tricky and potentially dangerous, if you don't know what you're doing. While I have used it in production, it was only on systems that I would be administering. If I implemented a solution that was to be turned over to another group for administration, I would not do this. Simon makes a very good point that the dangers far outweigh the advantages in this case. Still, I hope that demonstrating how it can be done sparks some interest in learning more about how the internals of the filesystem work. Use with caution!

Road trips
As a freelance consultant, I have to pay for all conference expenses -- as well as the lost income that I could have been earning while at the conference -- out of my own pocket. Therefore, I'm pretty careful about my conference selections. I had been told that the one conference I should be sure to attend was the Black Hat Briefings; next in priority was the hackers conference, Defcon. I was unable to attend either because of scheduling conflicts, but I asked some friends to provide feedback so I could decide if I should go next year. I independently asked a hacker, an editor, and a Wall Street colleague for their opinions. Strangely enough, they agreed on most points.

Black Hat
I did not see much press coverage of the Black Hat Briefings, although this was touted to be the security professional's conference, with plenty of leading-edge technical information. The admission price of $1,000 seemed pretty steep. Was it worth it?

Organization
The hotel was impressive, but just barely finished. Environmental alarms were constantly going off in the main conference room during talks. There were a couple of changes announced at the opening; otherwise, things went pretty smoothly. The most common complaint was poor scheduling: often two or more intriguing talks would be happening at once, while at other times there was nothing of interest going on.

Content of talks
The general consensus was that the talks were rather light on technical content. Most of the talks were targeted for law enforcement and upper management. Those that did have a technology focus were on an introductory level -- nothing new. The most notable session was Jennifer Grannick's talk on computer crime law. I specifically asked one person for a comparison to the SANS Network Security Conference (NetSec), which was held last October in Orlando. He felt the NetSec conference was more technical and more polished. It was also only half of Black Hat's price. (Disclaimer: I don't work for SANS and, in fact, did not care for the NetSec conference.)

Overall
The general impression I got was that Black Hat was interesting to attend and a good way to make contacts with people -- as long as someone else was paying for it.

Defcon
Defcon started out with what some might consider poetic justice: its Web page was defaced. While this didn't seem to be taken very seriously, it demonstrates that no one is immune to security problems.

Organization
I heard overwhelming complaints about the facilities and lack of organization. Some specific points made were:

Content of talks
No one I spoke to seemed to be too happy with the quality of the talks presented, either. Overall, the technical content was considered light. Some specific points made were:

The most useful presentation (some said the only reason for going) was the Cult of the Dead Cow (cDc) Back Orifice 2000 launch, which had all the restraint of a rock concert. A few dozen advance copies were thrown out to the crowd. Unfortunately, these were accidentally infected with the CIH virus. While I think it's commendable that cDc members eventually accepted responsibility, perhaps more attention should have been paid to quality control and less on theatrics (my opinion).

Overall, the motivation for attending either conference seemed to be the ability to network with people. It's a great opportunity to meet government agents, law enforcement, security professionals, hackers and, of course, the media. Who knows? Maybe your picture will show up on the news. I'm still not sure if I really want to spend my summer vacation in the desert. Why don't they do these things at the beach?

Acknowledgements
Grateful appreciation to Brian Martin (Attrition) and Space Rogue (Hacker News Network, and yes, that's his legal name) for their detailed feedback on Black Hat and Defcon. As always, much appreciation to Jonathan Klein for his programming expertise. Maybe one of these days I'll get him to explain Kerberos.

Disclaimer: The information and software in this article are provided as-is and should be used with caution. Each environment is unique and the reader is cautioned to investigate with his or her company as to the feasibility of using the information and software in the article. No warranties, implied or actual, are granted for any use of the information and software in this article and neither author nor publisher is responsible for any damages, either consequential or incidental, with respect to use of the information and software contained herein.


Click on our Sponsors to help Support SunWorld


Resources

Other SunWorld resources

About the author
Carole Fennelly is a partner in Wizard's Keys Corporation, a company specializing in computer security consulting. She has been a Unix system administrator for more than 15 years on various platforms and has particularly focused on sendmail configurations of late. Carole provides security consultation to several financial institutions in the New York City area.

What did you think of this article?
-Very worth reading
-Worth reading
-Not worth reading
-Too long
-Just right
-Too short
-Too technical
-Just right
-Not technical enough
 
 
 
    

SunWorld
[Table of Contents]
Subscribe to SunWorld, it's free!
[Search]
Feedback
[Next story]
Sun's Site

[(c) Copyright  Web Publishing Inc., and IDG Communication company]

If you have technical problems with this magazine, contact webmaster@sunworld.com

URL: http://www.sunworld.com/swol-08-1999/swol-08-security.html
Last modified:

SidebarBack to story

Messages from Doug Pardue and Garrett Roy

Message from Doug Pardue

From: Doug Pardue

This is on Mark Minasi's site (a renowned Windows NT guru), http://www.minasi.com/legend.html. I thought you might get a kick out of it after reading your article on social engineering.

Return to article

Message from Garrett Roy

From: Garrett Roy
Subject: chain letter response

Like most people I get inundated with virus hoaxes, chain letters and cute little ASCII art e-mails. (Well, they're cute the first time. They're just annoying the 257th time.) I recently got another warning about the "California" virus from my cousin (she really means well) and decided that enough was enough. I hit "reply to all" and sent the URL for "Urban Legends" and the Data Fellows virus hoax page. I received a concerned reply from one of the people on her distribution list. The contents of my reply follow:

Sorry if I caused any concern. We have never met or corresponded before.

To explain how you received my reply: Xxxxx Xxxxxx is my cousin.

I've gotten several e-mails like this virus warning over the years and, in the hope of stemming some small bit of the tide I simply selected "reply to all" when responding to this latest one. I had hoped that anyone on the list who was tempted to forward it might hesitate or, even better, choose not to continue the chain if he or she got my message in time. Since your e-mail address was also on the list, you got a copy.

What many people do not seem to realize is that the e-mail message itself becomes the virus as well intentioned but unknowing e-mail users replicate it over and over again (just like a biological virus). Granted, it's not explicitly destructive, but it uses resources as it is replicated and distributed. Just for an example let's say everyone involved has only 20 people in their address book (let's just say I have a lot more than 100 in mine) and only half will forward the "warning." After just a handful of generations (say 7) there will be 22,222,220 copies of it floating around.

Here's the math:

Generation 1 sends 20 e-mail messages = 20
Generation 2 half of the 20 (10) send out 20 messages each = 200
Generation 3 half of the 200 (100) send out 20 messages each = 2,000
Generation 4 half of the 2,000 (1,000) send out 20 messages each = 20,000
Generation 5 half of the 20,000 (10,000) send out 20 messages each = 200,000
Generation 6 half of the 200,000 (100,000) send out 20 messages each = 2,000,000
Generation 7 half of the 2,000,000 (1,000,000) send out 20 messages each = 20,000,000

For a grand total of 22,222,220 e-mails created and sent.

That could happen in 1 day. Now let's look at some of the costs involved. There's the transmission of 22,222,220 e-mail messages, the storage of 22,222,220 e-mail messages, many of the 22,222,220 people involved will have to dial out to their ISP to retrieve the messages, and then 22,222,220 people will have to take the time to at least briefly scan the message before they either delete or forward it. Digest that for a moment and then consider an example where you assume there are 60 addresses in each address book but only 20 recipients forward the message:

Generation 1 sends 60 e-mail messages = 60
Generation 2 one third of the 60 (20) send out 60 messages each = 1,200
Generation 3 one third of the 1200 (400) send out 60 messages each = 24,000
Generation 4 one third of the 24,000 (8,000) send out 60 messages each = 480,000
Generation 5 one third of the 480,000 (160,000) send out 60 messages each = 9,600,000
Generation 6 one third of the 9,600,000 (3,200,000) send out 60 messages each = 192,000,000
Generation 7 one third of the 192,000,000 (64,000,000) send out 60 messages each = 3,840,000,000

For a grand total of 4,042,105,260 e-mails created and sent.

Some people might say this is an extreme example, but I've got well over a hundred e-mail addresses in my address book, and I don't have all incoming addresses added automatically. Even if only 1 out of 10 forwarded it there would be a huge flood generated.

If you would like to get absurd ... here goes ... assume that the last group of recipients from generation 7 didn't forward it to anyone. They all took a measly 4 seconds to scan the message and decide to delete it. 3,840,000,000 messages x 4 seconds = 15,360,000,000 seconds used. Let's convert that to a unit of measure we can comprehend better.

15,360,000,000 seconds / 60 sec/min = 256,000,000 minutes
256,000,000 minutes / 60 min/hr = 4266666.66 hours
4266666.66 hours / 24 hrs/day = 177777.78 days
177777.78 days / 365 days/year = 487.06 years
487.06 years / 80 years/lifetime = 6.09 lifetimes

6 lifetimes ... and that is reading e-mail every second of every day from cradle to grave. Hmmmmmmmmm......

If you've gotten this far and you are still reading ... thank you. If you would like to find out more about e-mail virus hoaxes, etc. this site, http://urbanlegends.miningco.com, is an excellent source of information. Another site that deals specifically with e-mail and chain letters is http://www.chainletters.org.

I am now stepping off my soap box.

An apology is not necessary, but if, after following my little essay, the next time you get an e-mail chain letter or virus warning you decide to check out one of the Web sites I listed above (or one of the many Web sites that track real viruses), I would consider it a small victory.

After all of this I suppose I should mention that actual computer viruses can be a real threat, and you should exercise caution when downloading files from the Internet and opening e-mail attachments.

Now I offer an apology in the event that this has come across as a tirade. My purpose is not to offend but to educate.

Best wishes,
Garrett

P.S. Please don't immediately forward this to everyone in your address book ... but feel free to use this to respond to virus warning hoaxes in the future.

SidebarBack to story