Type packetstorm
Reporter Packet Storm
Modified 1999-08-17T00:00:00


                                            `Date: Wed, 8 Jul 1998 17:32:02 PDT  
From: Ezekial Morrow <paceflow@HOTMAIL.COM>  
Subject: SLMail 3.0.2421 Stack Overflow...  
Product: SLMail 3.0.2421 from Seattle Lab.  
Vulnerability: Stack overflow - Remote execution of code.  
Jeremy Kothe (  
If the "mail from" field exceeds 256 bytes, it will pass through the  
process without being trimmed... When the mail dispatcher picks up  
the mail  
file to process, it copies it into a stack buffer of only 256 bytes,  
overwriting the function return address and normally halting the  
The DOS attack is simple - simply send an e-mail with "mail from" >  
256 bytes.  
To exploit the attack to remotely execute code is difficult but NOT  
impossible. The main difficulty is that the string which overflows  
the stack  
(the "mail from" name) can contain only valid email address  
But don't think that makes it impossible...  
Stack overflows under xnix are usually a simple affair - create a  
and pipe it to the attacker.  
Under Windows 95 or Windows NT, however, the task is a little more  
If you are not familiar with basic win32 stack overflow methods, see  
dildog's excellent (although 40 iq points too dumb for most of us:})  
at http:\\www.cultdeadcow, as well as his contributions at  
Microsoft's under-rated (though limited) WinDbg to debug and examine  
the fault.  
Borland's Turbo Assembler and DataRescue's IDA (disassembler) for  
converting my code into data bytes (no, sorry, I refuse to remember  
0x50 is push eax... oh shit).  
Borland Delphi - my 3gl of choice for the Windows environment to  
and send the e-mail. Any ip-capable platform could of course be used  
Gaining Control  
The idea behind ANY overflow execution exploit is to leverage a bug  
or crash  
to execute data. To do anything, we must first "snag the EIP".  
To do this, we must examine the environment produced by the initial  
crash, find somewhere a pointer to our data, and then somhow get it  
into the  
eip register...  
So let's take a look at the environment created when SLMail  
Fire up SLMail.exe (it's a service, so use "net start slmail" or the  
control panel), then start WinDbg and Attach (F6) to the SLMail  
process. Press F5 to continue execution...  
Now we create a test program to send a buffer of 1600-odd 0x61  
("a")'s as  
the email from address. Running this program, our e-mail is accepted  
placed, as a file, into SLMail's "In" subdirectory. SLMail.exe then  
picks up  
this file and bang... WinDbg reports our first-chance-exception at  
0042263C mov ecx, [esp+114h+arg_0]  
00422643 mov edx, [esp+114h+arg_4]  
0042264A mov eax, [esp+114h+var_104]  
0042264E pop edi  
0042264F ==> exception mov [ecx], esi  
00422651 mov [edx], eax  
00422653 mov eax, ebp  
00422655 pop esi  
00422656 pop ebp  
00422657 pop ebx  
00422658 add esp, 104h  
0042265E retn  
The memory address which is being written to here happens to be  
which we see four lines above as being the procedure's first argument  
on the  
stack... Looking at the registers, we find that the stack area has  
well and truly overwritten by our test data, and that several  
(esp, esi, edi) are pointing to areas within this data area. And if  
we can  
stop the exception at 0x42264f, and the next one at 0x422651, then  
the retn  
will return to 0x61616161, or whatever else we choose to feed it...  
To stop the crash, we need to find an address which is writable, and  
two copies of it into our buffer in the appropriate place...  
This would be no real problem except for our main limitation, the  
alphanumeric-only content of our buffer allows us only 1/1024 of the  
address space... So we search and search... Nothing in the main  
so one-by-one we check the dlls used. Now, this is where the issue of  
platform-dependency comes along. If we use an address in a dll, we  
binding the exploit to that version of the dll. Any other versions  
crash... Luckily, the proliferation of NT 4.0 sp3 platforms provide a  
of large dlls which are fairly constant... (ie: user32.dll,  
It's worth remembering that NT server and workstation binaries are  
so even by targeting only this one platform, an attacker could  
achieve a > 70% success rate on a random basis.  
So eventually, I found an address in a dll data segment which was  
valid for  
us to use, and plugged it in. Now we're past the crash...  
Returning to the stack via Microsoftware...  
Normally, at this point, you could open up the main executable in  
IDA, turn  
on showing of op-codes, then do a string search for a " 54 " (the  
for push esp). Ideally, what you're looking for is:  
push esp  
Of course this would not usually be done, but by seaching for " 54 ",  
can almost always find something like:  
add esp, 54h  
Which is really the same thing! Just ignore the "add esp, " and  
Again, this is made enormously difficult because of the 1/1024  
limitation... And in this case, dig as I might, I couldn't find  
at a valid address... The closest thing I could use were a few bits  
like this:  
push esp (actually an add esp, 54h)  
pop eax/ebx  
pop edi  
Now all this does is to get esp into eax. Doesnt seem like much until  
realise thats it's relatively common to do a "call eax" or "call  
So, we go and find ourselves a "call eax/ebx" statement again with a  
(alphanumeric) address. We find a "call ebx" which we can use, so we  
back and find a variant of the above code snippet which moves our esp  
Positioning these two addresses at the correct position in the buffer  
can be  
tricky, but eventually we end up returning to what was originally our  
The first stage of the attack is over, and were it not for the  
limitations, the battle would be over.  
Executing Text  
We have control of the eip... cheer, rest, think.  
What can we put in our buffer to execute? Not bloody much.  
Every byte in our buffer MUST be valid alphanumeric.  
I wouldn't have come this far without a plan, though. My idea is to  
what small instruction set we DO have to dynamically CREATE a more  
piece of code.  
Checking the instructions available to us in the character set we  
have, I  
find that we have all of the "push"es and most of the "pop"s.  
Along with, luckily, the "-" character, which turns into a "sub eax,  
I came up with a plan... The initial code would PUSH the program onto  
stack, then execute it from there. The first trick is to push bytes  
cannot be in our buffer, I came up with the following:  
push xxxxxxxxh  
pop eax  
sub eax, xxxxxxxxh  
sub eax, xxxxxxxxh  
push eax  
Effectively, this means that for each DWORD of the target program, we  
to calculate a series of valid DWORDs which subtract from one-another  
produce the target DWORD... Sounds tough, but it turns out that a bit  
brute force solves this one easily. I wrote a fairly simple program  
which calculated these numbers and produced code for me to cut and  
After we've pushed this program onto the stack however, we need then  
jump or call to it. Unfortunately our limited instruction set has  
only short  
jumps, which limits our range so much we'd have to chain them. The  
location of the stack pointer, and therefore the pushed program, is  
above our current location ( where we are pushing the program ).  
So, instead of chaining short upwards jumps which would be hell to  
and maintain, I inserted a series of "popad" instructions to move the  
pointer down, over and past the push code, allowing only enough room  
the target program. The program is then pushed onto the stack and  
no jump or call needed. We have created the program in front  
of our eip and we naturally execute into it. Tricky, but by leaving a  
of room at the end of the "push"ing routing filled with harmless "inc  
instructions, it works fine.  
So, by using about 6-16 bytes per DWORD, we can create and run a  
program. At this rate, we would rapidly run out of room in our buffer  
to do  
anything. So, we add another trick. The program we produce is a small  
decompression routine. Using a simple nibble to byte compression  
routine to  
encrypt our main program and place it elsewhere in the buffer. This  
a 2 DWORD to 1 DWORD compression ratio, and a larger main program.  
The decompression routine is simple enough:  
; assume edx points to source area  
mov esi, esp  
add esi, 122 ; source from esp...  
; get length of code...  
xor ecx, ecx  
mov cx, word ptr [esi]  
add esi, 2  
sub cx, 6161h  
mov bx, cx  
shr cx, 4  
or cl, bl  
; decode code...  
mov eax, [esi]  
add esi, 4  
sub eax, 61616161h  
mov ebx, eax  
shr eax, 4  
or al, bl  
mov ebx, eax  
shr eax, 4  
mov al, bl  
ror eax, 0ch  
shr al, 4  
rol eax, 0ch  
push ax  
loop decode  
call esp  
Where Do We Want To Go Today?  
Game over, We can run ANY code we want at this point.  
I have included a full exploit program which simply create a file in  
current called "md9.exe" containing the text string  
"SLMail contains a stack overflow",  
but it could just as easily be downloading a complete .exe using  
the inet32 api, or other means. This program could in turn re-start  
SLMail service, remove any offensive log entries etc...  
Seattle Lab have played down response to concerns over overflows in  
the VRFY argument of versions 2.5 and 2.6 of SLMail. They said that  
security risk was minimal. Too hard to exploit, they said.  
As it turns out, the overflows in 2.5&6 are THE SIMPLEST POSSIBLE  
They are direct overflows with no major limitations on character set.  
So you can skip all the de-compression and pushing-of-programs, and  
valid addresses now means only avoiding 0's...  
I wrote this exploit in less than two days. Thats from the time I  
the evaluation copy of SLMail to the time I had arbitrary code  
executing on  
it. Now I'm not a bad guy, and I'm not paid to do this. Imagine what  
governments around the world would be able to do with even a minimal  
The real message here is that this is not an isolated flaw. Buffer  
of one kind or another are notoriously common even today on the more  
xnix platforms, and even more common on Windows Services written by  
programmers who do not realise or understand how serious these  
problems are.  
Recent posting to security sites reveal buffer overflows in COMMON  
such as WS-FTP, SLMail, MDaemon, sendmail!!! and others.  
Any serious group of hackers would no doubt be yawning over my  
here. They would have pre-fabricated routines to slot into place for  
various kinds of common overflows, allowing any server to be attacked  
potentially via any service it offers. Of course the entire DOMAIN of  
attacked machine is subverted as well, so machines connected via LANs  
even WAN/IP are also vulnerable, even if they don't run any  
The US Congress is deliberating legislation which would make it  
illegal for  
the sites which distribute information like this illegal.  
The effect of this would be that the developers ( in this case  
Seattle Lab )  
would NOT EVEN KNOW the problem existed... Whilst ANY serious hacker  
have found and exploited it months ago...  
As an example, it is not hard to write an overflow test program for a  
protocol - be it SMTP, FTP, etc.  
Simply by running these test suites over each new server as it is  
the hackers identify vulnerabilities quickly and painlessly, then  
The large number of Server providers, and the LACK OF EDUCATION  
the authors of these programs remains a huge security risk to  
and privacy on the internet.  
The legislation assumes that what I am doing here is providing a  
manual for would be "bedroom teen-superhackers" (script kiddies).  
Instead, what I am doing is SHOWING WHAT OTHERS ALREADY KNOW. No  
from his bedroom will be able to use this technique to do any real  
If he or she were to try, they would be logged and caught without too  
The government teams and whoever else has a professional interest  
I hope Seattle Lab and others will read and understand, then STOP  
the "It would be too hard to exploit" excuse.  
Jeremy Kothe (  
P.S. Seattle Lab has been informed... No response yet.  
Get Your Private, Free Email at