Index Home About Blog
From: viro@weyl.math.psu.edu (Alexander Viro)
Subject: [clue filters] Re: Debian - The Distribution from Hell
Date: 2000/02/23
Message-ID: <891kot$7uj@weyl.math.psu.edu>
Approved: foo
References: <88eeuq$ee7$1@news.huji.ac.il> <apog88.mfc.ln@clickstream.greencathedral.co.uk> <ud7pv7v6p.fsf@home.se> <88udvb$8u4$1@peabody.colorado.edu>
Organization: -ENOENT
Newsgroups: alt.sysadmin.recovery

In article <88udvb$8u...@peabody.colorado.edu>,
Matthew Crosby <cro...@nagina.cs.colorado.edu> wrote:
>Ah, kids today.  dselect as a clue filter?  What happened to the old
>faithful trio,  sendmail.cf, ed and adb macros?
>
>I knew I'd been SAing too long when I was able to use ed comfortably
>without once looking at the manuals
>
>Such a pity these have gone away.  I mean, no one needs to rebuild boxes
>without term* or whatever anymore, so ed's gone, that sissy m4 stuff has
>come in for sendmail, and as for adb, Sun's new mdb is extendable with c
>(though doesn't currently support an interpreted language other then
>good ol adb; they claim none really can quite do the job, and it's true
>that perl, python and tcl are all a little lacking on the ol manipulate
>kernel data structure front).
>
>And now one doesn't need to go through setting up X at the config level,
>or downloading all 40 disks of SLS, or even building your own kernels.
>We come to the point instead where _dselect_ is considered a filter.
>What can we do to stop today's kids getting soft?  Require them all to
>run Plan 9?  Program in Intercal?
>This is a serious problem, fellow BOFH's, one we need to think about.

[Warning: the following is true story and if the stuff below will ever
become UI for you - accept my condolence. It _is_ scary, so think before
reading further]

Give them what I got yesterday. As in, box that got
	a) Linux kernel running.
	b) init and bash running.
	c) serial and floppy - built as modules. And not loaded.
	d) no sash.
	e) no ethernet.
	f) bloody large number-crunching that Should Not Be Aborted(tm).
	g) libc and ld-linux.so - unlinked (self-LART by owner).
Now, I could tell the guy to piss off, but... WTF? He had decent beer and
was properly scared. Oh, well... So we have no exec() for anything dynamically
linked. And we have no chance to access any external stuff - insmod is linked
dynamically, so no insmod floppy for you. Shutting the system down was not an
option due to (f) (aside of dealing with fsck later - umount(8) is dynamically
linked too). Now, I knew that both /lib/libc.so-2.1.2 and
/lib/ld-linux.so-2.1.2 were still alive - mmaped by init, for one. And
/proc/1/maps would even contain their inumbers. So the plan of attack was
to create a file in root and then cannibalize the entry (change inumber in
the directory). Alas - not enough. In-core inode got zero i_nlink and
if I would just create a link by hands it would not become positive. I.e.
still remove-upon-close. But. But if we will manage to call link() on the
hand-made link we will get i_nlink raised to 1 - iget() will find the same
in-core inode, so we are OK. We'll have to revert the phony link to avoid
PO'd fsck, but that's not a problem...
	So there we go: assuming that we got static ln
echo >foo
ln foo bar
flip inumber in foo entry to point to libc
ln foo /lib/libc.so-2.1.2
flip inumber.......................... bar
repeat for ld-linux.so
rm foo bar
begin recovering other damage (self-LART was a bit larger).
	But... we don't have this flip stuff and we don't have (aaarrgh) static
ln. Oh, shit... OK, but all we really need is a couple of syscalls, right?
There we go:
	eax=__NR_link;
	ebx=s1;
	ecx=s2;
	int 0x80;
	eax=__NR_exit;
	ebx=0;
	int 0x80;
s1:	"foo"
s2:	"bar"
The next step was getting the syscall numbers. grep? We don't need no stinkin'
grep.
# while read i; do case $i in *__NR_link*) echo $i;; esac;
done </usr/include/asm/unistd.h
#define __NR_link 9
# while read i; do case $i in *__NR_exit*) echo $i;; esac;
done </usr/include/asm/unistd.h
#define __NR_exit 1
#define __NR__exit __NR_exit

Now, scratching the head and recalling intel code...
start:  b8 09 00 00 00
	bb (address of s1)
	b9 (address of s2)
	cd 80
	b8 01 00 00 00
	bb 00 00 00 00
	cd 80
s1:	66 6f 6f 00
s2:	62 61 72 00

Fine, but... a.out support is compiled... you guessed it, as module and not
currently loaded. So we are in for crufting up an ELF binary. OK, we don't
actually need 100%-correct ELF, just something that will pass for the
exec(). Now, we don't have shell scripts, but . will work. So the next
step was rolling more(1) in shell and reading through the relevant code
(surprisingly small - binfmt_elf.c and two headers). After much swearing
the following abortion was created:
7f 45 4c 46 00 00 00 00 00 00 00 00 00 00 00 00
02 00 03 00 01 00 00 00 start______ 34 00 00 00
00 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00
00 00 00 00 01 00 00 00 00 00 00 00 base_______
base_______ size_______ size_______ 05 00 00 00
00 10 00 00
start:
b8 09 00 00 00 bb start+1d___ b9 start+21___ cd
80 b8 01 00 00 00 bb 00 00 00 00 cd 80 66 6f 6f
00 62 61 72 00
OK, set base to something page-aligned, start=base+54, size=79. There we go:
7f 45 4c 46 00 00 00 00 00 00 00 00 00 00 00 00
02 00 03 00 01 00 00 00 54 00 00 80 34 00 00 00
00 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00
00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 80
00 00 00 80 79 00 00 00 79 00 00 00 05 00 00 00
00 10 00 00 b8 09 00 00 00 bb 71 00 00 80 b9 75
00 00 80 cd 80 b8 01 00 00 00 bb 00 00 00 00 cd
80 66 6f 6f 00 62 61 72 00

well, while read l; do for i in `echo $l`; do echo -ne "\\$i"; done; done
made for oct2bin, overwriting /usr/bin/emacs with the output of that gave
us static equivalent of ln foo bar. And it worked. The rest was essentially
the same - the only tricky part was to find the location of directory entry.
Which was done with (lseek, read byte, exit(said_byte)) and shell wrapper
around that. So we had a way to read a block and dump it on the console.
The rest was obvious - start from relevant block in inode table and walk
through the references... Once we got that, it was an easy ride - trick
with inumber flipping brought libc and dynamic linker back and after that
we had 99% of system back into the working state. Amazing how little you
actually need to bring the system back to life...

--
All that blue light from Orthanc at night? That was Saruman, trying to
moderate news.admin.palantir-abuse.sightings.
					Mike Andrews in the Monastery


Index Home About Blog