|
|
|
|
|
Unfortunately, not many mailers allow you to define the domain name
they
pass and even less capable to handle a 1kb string as a valid domain
name.
Of course, one can write his own mailer or modify an open source
one, but
I preferred to play with Netmail, which I am using currently.
Netmail 95 2.12 (Nm95.exe 73728 bytes) is a free (but not open source)
win32 command line mailer which sends text files as emails and
puts
incoming emails into text files.
It also comes with a gui configuration tool (Nm95cfg.exe 76800
bytes) to
set different parameters like incoming and outgoing directory,
etc.
Everything is as simple as can be, just the way I like it.
It also lets you define the domain name to be used in the HELO
command
which is a good start. :)
Cracking Nm95cfg.exe:
Start Nm95cfg.exe create a new config file and fill in the relevant
info.
The first textbox on the server tab asks for the domain name, that's
what
we have to mess with. You also have to set the SMTP, POP server
etc.
All these info are saved into the freshly created Nm95.cfg file.
Open and study the file, create a new one and study it too.
The next conclusions can be drawn:
- the file is 590 bytes long (all numbers are hexadecimal further
on)
- each entry is fixed length, so shorter strings are padded with
zeros
longer strings are trimmed
- the order of entries and their offset from the beginning of the
file:
Entry
Offset(bytes)
"NetMail 20 CFG" string
0
domain name
10
incoming folder
50
outgoing folder
A0
smtp server
F0
pop server
130
pop username
170
pop password
1F0
log file
230
number of mail in inbox 280
dialup connection name
284
dial up user name
385
dial up password
486
flood protection
588
delete large messages
58C
It is clear that we have to modify Nm95.exe to make it handle a
400 bytes
long string as the domain name instead of the 40 bytes long we
see here.
Lets check how Nm95cfg.exe handles this file. Disassemble Nm95cfg.exe
with wdasm and load the process. Set break points on ReadFile function
calls (two locations) and let it run.
We break at 403BC3 on the ReadFile call, and wdasm api viewer tells
us
what are the arguments of the call.
arg1, file handle = 06
arg2, address of buffer receiving the data = 660078
arg3, number of bytes to read = 1000
arg4, address of number of bytes actually read = 64Fd34
arg5, address of overlapped data = 0 (not important now)
The most important information here is, that the program is able
to
read 1000 bytes data which is much more than the original 590 plus
the 400 extra bytes we would like to add to the cfg file, so
we do not have to worry about the ReadFile function.
It worth to note that all the data is read in one big chunk, meaning
that must be a variable (a structure or a string) in the program
which
will hold all the data after the read is completed.
After the read file function we single step with F8 through some
error
checks until we see that the program starts to copy the data from
the
input buffer at 660078 to its final location at 409C60. This happens
at 40255A code position. Let it finish the copy and single step
until
you find the call which initiated the whole read process at 4010AE.
Here is a code snippet from that location:
:004010A0 and eax, 00000008
:004010A3 add eax, 00000588 ;8+588=590 !
:004010A8 push eax
;push the length of the file = 590
:004010A9 push 00409C60
;push the address where to read !
:004010AE call 004024E0
;read the data
:004010B3 add esp, 00000010
:004010B6 cmp eax, 00000001 ;successful?
:004010B9 jne 00401374
;if not damaged config file
:004010BF test ebx, ebx
:004010C1 jne 004010DF
;old config file
:004010C3 push 00000010
* StringData Ref ->"NetMail95 20 CFG"
|
:004010C5 push 00408094
;file title
:004010CA push 00409C60
;beginning of data
:004010CF call 004024A0
;check if the title is correct
:004010D4 add esp, 0000000C
:004010D7 test eax, eax
:004010D9 jne 00401374
;if not damaged config file
.
.
.
;start processing the individual entries
:00401100 mov edi, 00409C70 ;domain name string
!
:00401105 mov ecx, FFFFFFFF
:0040110A sub eax, eax
:0040110C repnz
;get the length
:0040110D scasb
:0040110E not ecx
:00401110 sub edi, ecx
:00401112 mov eax, ecx
:00401114 shr ecx, 02
:00401117 mov esi, edi
:00401119 mov edi, 00409114 ;address of the new
string variable !
:0040111E repz
;copy to the new variable
:0040111F movsd
:00401120 mov ecx, eax
:00401122 and ecx, 00000003
:00401125 repz
:00401126 movsb
:00401127 mov edi, 00409CB0 ;continue with, incoming
folder string .etc
The important information here is that the program refers to the
begining of the data by a fixed address 409C60 which means that
a global structure holds our data. We can get the address of each
entry by adding the offset of the entry we calculated previously
from the Nm95.cfg file to 409C60. The domain name is at address
409C70. In the source code the structure might have been looking
like this:
typedef struct
{
char title[10];
char domain_name[40];
char incoming_folder[50];
.
.
.
int del_large_mesage;
} configdata;
At 401100 the program starts to copy the members of the structure
into individual variables which are associated with the text boxes
on the form. The string variable containing the domain name is
at
409114 and the length of the string is stored at 409110 (already
set to 40).
We now know, how the data is read and put into string variables.
We only have to find how where it is copied back into the structure
before the config file is saved. We only have to search for the
references to 409114 to find the important code pieces.
Here the content of the textbox is copied into the string variable:
:004017E8 push 00409114
;string variable !
:004017ED push 00000104
;get 104 characters !
* Reference To: USER32.SendDlgItemMessageA, Ord:01C4h
|
:004017F2 mov esi, dword ptr [0040C1E4] ;send
message
:004017F8 push 0000000D
;WM_GETTEXT
* Reference to Dialog: DialogID_006D, CONTROL_ID:04D6, ""
|
:004017FA push 000004D6
;domain name textbox
:004017FF push ebx
;parent window
:00401800 call esi
;get the text
And here the data structure is filled from the variables before
it
gets saved into the config file:
* StringData Ref ->"NetMail95 20 CFG"
|
:004013E0 mov eax, dword ptr [00408094] ;All
these magic here is to put
:004013E5 push esi
;the string "NetMail 20 CFG"
:004013E6 mov esi, dword ptr [00408098] ;to address
409C60 at the
:004013EC mov dword ptr [00409C60], eax ;beginning
of the structure
:004013F1 mov eax, dword ptr [0040809C]
:004013F6 mov dword ptr [00409C64], esi
:004013FC push edi
* StringData Ref ->"NetMail95 20 CFG"
|
:004013FD mov ecx, 00408094
:00401402 mov dword ptr [00409C68], eax
:00401407 mov edx, 00409C60
:0040140C mov ecx, dword ptr [ecx+0C]
:0040140F push 00000040
;finally, here take 40 bytes !
:00401411 push 00409114
;of the domain name and !
:00401416 mov dword ptr [edx+0C], ecx
:00401419 push 00409C70
;copy it into the structure !
:0040141E call 004013B0
;do it
:00401423 add esp, 0000000C
:00401426 push 00000050
;50 bytes of the incoming
:00401428 push 00409420
;folder string is put
:0040142D push 00409CB0
;into the structure, etc
:00401432 call 004013B0
;do it
Now, we can design our 'crack':
- First, we have to make a new structure which has a 400 bytes
long
domain name entry instead of the original 40 bytes. We cannot just
enlarge the structure at its original position because it would
overwrite
several other variables. We have to find a 950 bytes long empty
space
and put it there. Then we have to redirect all references to the
old
structure to the new one. (We have to modify all references to
the
size of the structure to the new size, too).
- Second, we have to create a 400 bytes long string variable to
hold
the domain name and redirect every reference from the original
string
variable to this one. (Also every reference to the size of the
string
must be modified to be 400.)
- Finally, we have to patch the code where the string is filled
from the textbox to let it copy 400 bytes instead of 104.
Where can we put the new 950 bytes long structure? We could create
a new
section to the program to hold our data, but it is not nice to
increase
the size of a nice compact program. Instead we can try to squeeze
it
into the padding space of the .data section. With Dumppe we get
the
next info: (for info on the PE header please see here.)
03 .data Virtual Address
00008000
Virtual Size
00003324
Raw Data Offset 00006000
Raw Data Size
00001000
Relocation Offset 00000000
Relocation Count 0000
Line Number Offset 00000000
Line Number Count 0000
Characteristics C0000040
Initialized Data
Readable
Writeable
It tells us that the section starts at 408000 (400000 is the image
base)
and 3324 bytes long so it lasts to 40B324 (both the original structure
and the domain string are in this space). The sections are aligned
to
1000 so the next section starts at 40C000 therefore we have CDA
byte long
padding from 40B325 to 40BFFF. This is enough to hold our new 950
bytes
structure, but not enough for both the structure and the new 400
bytes long
string (D50 bytes). On the other hand we can use the original place
of
the old structure, which will not be used anymore to hold the string.
This way we do not have to add more sections and increase the program
size.
We will put the new structure at 40B400 and the new string at 409D00.
(This nice round numbers make calculations easy :)
Here are the addresses of the structure we have to modify:
Entry
old
new
title
409C60 40B400
domain name
409C70 40B410
400 bytes now!
incoming folder
409CB0 40B810
outgoing folder
409D00 40B860
smtp server
409D50 40B8B0
pop server
409D90 40B8F0
pop username
409DD0 40B930
pop password
409E50 40B9B0
log file
409E90 40B9F0
number of mail in inbox 409EE0
40BA40
dialup connection name 409EE4
40BA44
dial up user name
409FE5 40BB45
dial up password
40A0E6 40BC46
flood protection
40A1E8 40BD48
delete large messages
40A1EC 40BD4C
additional references
409C64 40B404
into this region
409C68 40B408
All references in the program to these addresses have be modified.
At code 4010A3 the reference to the size of the structure should
be
changed from 588 to 948 and at 40158C from 590 to 950. We are done
with the structure.
The domain name string references we have to modify:
reference
old
new
length
409110 409D00
string
409114 409D04
Again the reference to the size of the string at 40140F has to be
set to 400. Because we need one extra byte to do this we have to
rewrite this part of the code a bit.
Here is the original code:
* StringData Ref ->"NetMail95 20 CFG"
|
:004013FD B994804000 mov ecx, 00408094
! here
:00401402 A3689C4000 mov dword ptr [00409C68], eax
:00401407 BA609C4000 mov edx, 00409C60
:0040140C 8B490C mov ecx, dword ptr
[ecx+0C] ! here
:0040140F 6A40 push 00000040
:00401411 6814914000 push 00409114
The two lines marked with ! does nothing more, but moves the " CFG"
string into ECX. We can get our extra byte if we replace these
two
instructions with one like this:
:004013FD B920434647 mov ecx, 47464320
;move " CFG" into ECX
:00401402 A3689C4000 mov dword ptr [00409C68], eax
:00401407 BA609C4000 mov edx, 00409C60
:0040140F 6800040000 push 00000400
;here we have 400 bytes
:00401411 6814914000 push 00409114
Finally, at code 4017ED we have to modify the number of bytes read
from the textbox into the string from 104 to 400.
We are done, Nm95cfg.exe can handle a 400 bytes long string as
domain
name now.
Cracking Nm95.exe
To actually send an anonymous email we also have to patch Nm95.exe
to
make it capable to read and send the 400 bytes long domain name.
Because the crack is exactly the same as before I only describe
it
in a nut shell. The structure is located at 411960 and we move
it to
413400.
Entry
old
new
title
411960 413400
domain name
411970 413410
400 bytes now!
incoming folder
4119B0 413810
outgoing folder
411A00 413860
smtp server
411A50 4138B0
pop server
411A90 4138F0
pop username
411AD0 413930
pop password
411B50 4139B0
log file
411B90 4139F0
number of mail in inbox 411BE0
413A40
dialup connection name 411BE4
413A44
dial up user name
411CE5 413B45
dial up password
411DE6 413C46
flood protection
411EE8 413D48
delete large messages
411EEC 413D4C
Length of the structure has to be changed at 4035AB and 403818 from
590 to 950.
The buffer where the domain name is combined with HELO is located
at
411000 and we move it into the place of the structure at 411960.
(The buffer can hold 3E8 bytes of data, but that's not enough for
us.) Because this is the main input-output buffer for socket communication,
there are a lot of references to it all over the program, but we
only
have to change the two references connected with the HELO sending:
:00401B7E push 00411970
;this we already changed to 00413410
* StringData Ref ->"HELO %s"
|
:00401B83 push 0040E678
:00401B88 push 00411000
;here, relocate the buffer to 00411960!
:00401B8D call 00405227
;put HELO and domain name together
:00401B92 mov ecx, dword ptr [00410DA0]
:00401B98 push 00411000
;here, relocate the buffer to 00411960!
:00401B9D push ecx
:00401B9E call 004013A0
;send through socket
We are now ready to send our anonymous email.
Here is a header of an email sent by the modified Netmail through
an
SMTP server with Sendmail 8.8.5. when we specified the domain name
as 400 bytes of dashes :): (Line breaks inserted by me.)
Received: from deep-cover.mit.edu [18.251.3.197] by mx04
via mtad (2.6) with ESMTP id 337DiqFhR0115M04;
Fri, 17 Sep 1999 05:33:17 GMT
Received: from -----------------------------------------
--------------------------------------------------------
--------------------------------------------------------
--------- lots of dashes :)
Date: Fri, 17 Sep 1999 01:33:12 -0400
From: nobody@nowhere.net
Message-Id: <199909170533.BAA07671@deep-cover.mit.edu>
To: undisclosed-recipients:;
Seems it is working :)
|
Zer0+
Greetings to +everybody
|
homepagelinkssearch_forms+ORChow
to protectacademy
database
reality
crackinghow
to searchjavascript
wars
toolsanonymity
academycocktailsantismut
CGI-scriptsmail_fravia+
Is
reverse engineering legal?