|
Summertime potluckThis mixed bag of goodies includes additional tidbits on sendmail and chroot |
In this month's column, Carole ties up some loose ends left over from previous columns onsendmail
andchroot
(padded cells). Thecheckcompat()
routine is discussed, as well as a method for defeating a possible exploit againstchroot
. As an added bonus, some review of the Black Hat briefings and Defcon. (3,000 words)
Mail this article to a friend |
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
|
|
|
|
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:
..
" reference in cell_top
for this directory
cell_top/tmp/loser
; this will allow for a
new reference for "..
" in the cell_top
directory
cd
into
cell_top
and assign "..
" to be the directory cell_top/tmp/loser
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 achroot()
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 anlstat()
, usingmknod()
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.
|
Resources
chroot()
jail:
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.
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:
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.
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.