win32 – Grey Panthers Savannah https://grey-panther.net Just another WordPress site Fri, 31 Jul 2009 10:37:00 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.3 206299117 Patching lcc-win32 so that it runs under Windows 2000 https://grey-panther.net/2009/07/patching-lcc-win32-so-that-it-runs-under-windows-2000.html https://grey-panther.net/2009/07/patching-lcc-win32-so-that-it-runs-under-windows-2000.html#respond Fri, 31 Jul 2009 10:37:00 +0000 https://grey-panther.net/?p=243 lcc-win32 is a small C (not C++!) for Windows, which comes with a simple editor/IDE. It is free for non-commercial use and is small and quick to install. Unfortunately it wouldn’t start on a fully patched Windows 2000 SP4 box, even though the homepage explicitly mentions Windows 2000 as supported. The problem was that my system, for whatever reason, had an older version of SHELL32.DLL, which didn’t contain/export a required method. So I patched the executable and redirected the given import to an other import (ie. the loader would use a different import) and NOP-ed out the code which used the given import (fortunately it was used only in a single location, which wasn’t critical). Below you can see a video of the process:

The error message:

wedit.exe - Entry Point Not Found

The procedure entry point SHGetFolderPathAndSubDirW could not be located in the dynamic link library SHELL32.DLL

Tools used:

Here is the script which is shown in the background:

  • Patching lcc-win32 so that it runs under Windows 2000
  • We try to run the editor and we see that it (in fact the windows loader) errors out saying that it can’t find a given export in SHELL32.DLL
  • Bonus tip: you can copy the contents of a message box by pressing Ctrl+C when given focus.
  • Ok, we open up the executable in IDA to asses the situation (we already generated the idb file to speed up the demo)
  • Using cross-references we see that it is only used in one place, and even that doesn’t seem crucial.
  • So we edit the IAT of wedit.exe so that it imports an other function instead of the original one (so that it loads).
  • For safety we NOP out the call code. We must NOP out the pushing of the parameters and the call to keep the stack in sync.
  • Finally we test that everything works.
  • Thank you for your attention!

So you see, things can be fixed, even when you don’t have access to the source code, but it is nicer (and less complicated) when you do. Hopefully this will help somebody out 🙂

]]>
https://grey-panther.net/2009/07/patching-lcc-win32-so-that-it-runs-under-windows-2000.html/feed 0 243
What can a malicious program do under a limited account with Windows 7? https://grey-panther.net/2009/07/what-can-a-malicious-program-do-under-a-limited-account-with-windows-7.html https://grey-panther.net/2009/07/what-can-a-malicious-program-do-under-a-limited-account-with-windows-7.html#comments Thu, 09 Jul 2009 19:23:00 +0000 https://grey-panther.net/?p=276 The scope of this post is to demonstrate what a malicious program can do under Windows 7 (the newest and presumably most secure version of MS Windows) with a Guest account (the most limited one from a capability point of view). The “malware” in the video below demonstrates that a program run by the user (we can imagine tricking the user using social engineering) still can:

  • Access the user files from MyDocuments
  • Perform keylogging
  • Take screeenshots

Sorry for the typos in the text but I hope that the point came across that with minimal modifications malware can be made “compatible” with more restricted environments than what it is used by default by a large percentage of the population. While malware running in these conditions wouldn’t have access to advanced capabilities (like kernel-mode rookits), it can still inflict a lot of damage in the time-window between the infection and when it is detected. This window can be even expanded by using tools like server-side polymorphism.

My conclusions would be:

  • Limited accounts are a great tool, but only because most (almost all) malware wasn’t written with it in mind. Probably this will change in the future as
  • Any executable (which can take many forms) running under the current user can access anything the current user can, which is probably all the information the user cares about!

I wish to emphasize again that the environment tested is was much more restrictive than the user accounts created by default by Windows 7, and even so, the malicious code could access all the data belonging to the user.

PS. I will not release the source code used for the demonstration in any form (binary or source code), because there is already enough malicious code out there. Then again, the code used is fairly standard and there are many examples out there and a little searching can lead anyone to it.

Update: re-uploaded the video, now in better quality.

Update: I recently found a video demonstration by PrevX which shows how Vanquish, an old user-mode rootkit, works perfectly well under Windows Vista (and most probably 7) with LUA.

]]>
https://grey-panther.net/2009/07/what-can-a-malicious-program-do-under-a-limited-account-with-windows-7.html/feed 3 276
Breaking into a process before the TLS gets executed https://grey-panther.net/2009/06/breaking-into-a-process-before-the-tls-gets-executed.html https://grey-panther.net/2009/06/breaking-into-a-process-before-the-tls-gets-executed.html#respond Fri, 26 Jun 2009 09:16:00 +0000 https://grey-panther.net/?p=294 I found out about this from the SANS blog: you can make Olly break before the TLS get executed. Just Debugging Options –> Events and set “Make first pause at” to “System breakpoint” instead of “WinMain”. Cool! (until now I was patching executables with TLS to avoid them being executed).

image

]]>
https://grey-panther.net/2009/06/breaking-into-a-process-before-the-tls-gets-executed.html/feed 0 294
Reason #341 for using stackoverflow.com https://grey-panther.net/2009/01/reason-341-for-using-stackoverflow-com.html https://grey-panther.net/2009/01/reason-341-for-using-stackoverflow-com.html#respond Fri, 30 Jan 2009 08:01:00 +0000 https://grey-panther.net/?p=434 I’ve written about stackoverflow.com, a place to ask and answer programming questions. And here is an other reason to use it: they have great error pages 🙂

so_error_page

And today I’ve learned something new on SO from Oliver Giesen (also, his SO profile): you can’t delete executable files which are “in use” (programs are being run from it), but you can rename them! I verified this with a small test program, and indeed, it is so. The same is true (not surprisingly) for DLL files. This trick can come in handy for cleaning malware.

]]>
https://grey-panther.net/2009/01/reason-341-for-using-stackoverflow-com.html/feed 0 434
It can happen to the best of us https://grey-panther.net/2008/10/it-can-happen-to-the-best-of-us.html https://grey-panther.net/2008/10/it-can-happen-to-the-best-of-us.html#respond Tue, 21 Oct 2008 11:07:00 +0000 https://grey-panther.net/?p=643 I was reading Scott Hanselman’s The Weekly Source Code 33 – Microsoft Open Source inside Google Chrome and came upon this piece of text:

Older versions of ATL, and by older I mean pre-Visual C++ 2005, used dynamically generated code in small isolated cases. Obviously, without the appropriate APIs this is going to cause problems on a DEP-enabled computer, because you can’t execute data. This code is referred to as a “thunk” and versions of ATL in VC++ 2005 and later work correctly with DEP.

I have a great deal of respect towards MS, even though I don’t agree with their philosophy. Still, their continuous stride towards “software perfection” is admirable and it helps us all (when they publish their methods / data ;-)). I suspect (haven’t verified it) that the given problem arose because the PAGE_EXECUTE flag wasn’t passed in that particular version of the library to the memory allocator. If this can happen in a MS library, it can happen to anybody. My conclusions would be:

  • When using a function, read the documentation carefully.
  • Follow the documentation! Example source is nice, but be very suspicious about it (even if it is provided in the documentation). Preferably use it to orient yourself but don’t copy-paste it.
  • You’re not safe even when using abstraction libraries (this is not to say that they shouldn’t be used, just to point out that everybody can make mistakes – although probably any high-quality library contains much lower rates of mistakes than you can achieve).
  • When new versions come out (of tools, libraries, etc) – update. Not immediately, but plan for it. It can fix a lot of problems which you never knew you had :-).
]]>
https://grey-panther.net/2008/10/it-can-happen-to-the-best-of-us.html/feed 0 643
Reboot Windows – the hard way https://grey-panther.net/2008/06/reboot-windows-the-hard-way.html https://grey-panther.net/2008/06/reboot-windows-the-hard-way.html#comments Mon, 16 Jun 2008 10:03:00 +0000 https://grey-panther.net/?p=702 I was clicking around via an RDP session on a Windows server and managed to kill the LSASS process (note to myself: next time pause the view of ProcessExplorer before killing processes!). The one minute till reboot screen promptly appeared and my first reflex was to stop the countdown (this is a trick which came in handy back when the lsass-killing worm was making the rounds). So I typed:

shutdown -a

My next step was to try to restart Windows (having no Local Security Authority process is not the best situation to be in). However I quickly found that:

  • The shutdown command wasn’t working
  • ProcessExplorer could not restart the computer because it was trying to aquire the shutdown privilege dynamically, and given that no lsass process existed, it failed

I also tried to start the lsass process, but to no avail.

My option was to wait until somebody shows up on site (which could take a couple of hours) or to do something else. Naturally I decided to do something else :-).

I remembered this source code which uses an undocumented API call to change the IOPL level of the process (meaning that you can read/write from/to the ports from user mode) and then uses the keyboard controller to create a hardware reset. Don’t do this at home 🙂

After compiling it, the first hurdle was to get it on the machine. LSASS not running, file shares were not working, but fortunatly I had access to a FTP server and used the command line FTP client to download the executable.

The second problem was to create a session with SeTcbPrivilege. Doing as described on the page was not really feasible (without LSASS the user management wasn’t really working and even if it were, I’m not sure that I could have logged back in). So I started CMD.EXE with the SYSTEM account, with the method described here, at which point I already had the required privileges.

The final problem was that the program contained code to aquire the privilege and checked for the return code. This call of course failed, not because I didn’t have the privilege, but because LSASS was not running. So I removed the error checking code, and voila!

The connection went silent, and I waited and waited and waited wondering if I did the right thing. After about four minutes the machine came back up. W00t! But as I said earlier: don’t try this at home!

]]>
https://grey-panther.net/2008/06/reboot-windows-the-hard-way.html/feed 3 702
Perl, Windows and File Locking https://grey-panther.net/2007/01/perl-windows-and-file-locking.html https://grey-panther.net/2007/01/perl-windows-and-file-locking.html#comments Wed, 17 Jan 2007 14:29:00 +0000 https://grey-panther.net/?p=918 $lock_file") or die("Failed to lock file $lock_file, error: $^E"); flock(LockFile, LOCK_EX) or die("Failed to lock file $lock_file"); The idea being that the OS guarantees […]]]> For some Perl scripts you want to make sure that only one instance of it is running at the same time. So you use lockfiles, in a way like this:

open(LockFile, ">$lock_file") or die("Failed to lock file $lock_file, error: $^E");
flock(LockFile, LOCK_EX) or die("Failed to lock file $lock_file");

The idea being that the OS guarantees you that only one process can have an exclusive lock on a file at a time (warning! this is true only on local file systems! don’t try this with networked file systems like Samba of NFS!)

All is nice and dandy until you try to execute other programs from inside your script. To make the problem more hands-on: let’s say you have the script A.pl which launches multiple instances of B.pl in a fire and forget manner. Let’s say that at one moment A.pl dies (or is killed) and you try to restart it. If you are on Linux, no problem, however on Windows you may be greeted by the messsage “failed to aquire lockfile”. So you fire up Process Explorer and make sure that no other instance of the script is running. Still you get the same error when trying to start up. The next step is to search for open handles to the given lockfile. Much to my surprise I found that instances of B.pl had handles opens to it.

How did they get it? The API for creating processes under Windows is CreateProcess (no surprise here), but look at the 5th parameter: BOOL bInheritHandles. Quote from MSDN:

[in] If this parameter TRUE, each inheritable handle in the calling process is inherited by the new process. If the parameter is FALSE, the handles are not inherited. Note that inherited handles have the same value and access rights as the original handles.

Now the source of the problem became clear: A.pl had a file handle open to the lockfile, which was inherited by each process launched by it. While the children process were running, you couldn’t restart the master process. But why doesn’t the problem appear on Linux? Because Larry Wall has thought of this problem, and decided (very sanely) that only three handles should be inherited by the child process by default: STDIN, STDOUT and STDERR. This is controlled by the $^F / $SYSTEM_FD_MAX variable. Unfortunately setting this variable has no effect whatsoever on Windows, since the file handles don’t start at 0 for it.

The first solution which came to mind was to replace each call of system with Win32API::CreateProcess, however there was the possibility that I may miss some system calls in current or future scripts.

My second idea was to intercept somehow the fork event and close in the child process the handle to the lockfile. This was a better idea, since I could do this once and it would take effect everywhere, however there was a problem: I couldn’t find a way to detect the execution of fork.

Here is the third and final solution. Only the locking subroutine must be modified and no additional burden is laid on the programmers using the subroutine (ie. they don’t have to remember to use some additional magic when running external programs):

First, include the appropriate library, but only if we are running Windows (to make the code cross platform compatible):

if ($^O =~ /Win32/) {
  use Win32API::File qw(:Func :HANDLE_FLAG_);
}

Now do the following after you opened the file handle to the lockfile:

if ($^O =~ /Win32/) {
  my $os_handle = GetOsFHandle(*LockFile); 
  SetHandleInformation($os_handle, HANDLE_FLAG_INHERIT, 0x0) if ($os_handle);
}

This will tell Windows that the handle shouldn’t be inherited by the child processes, even when the bInheritHandles parameter of CreateProcess is set to true (remember, the documentation said each inheritable handle, not each handle). For more details see the SetHandleInformation API page. Also remember that not only file handles but other type of handles (like event or mutexes) are also inherited and this method is also applicable to those.

]]>
https://grey-panther.net/2007/01/perl-windows-and-file-locking.html/feed 1 918
Perl and Windows https://grey-panther.net/2006/12/perl-and-windows.html https://grey-panther.net/2006/12/perl-and-windows.html#respond Sun, 31 Dec 2006 13:14:00 +0000 https://grey-panther.net/?p=943 Perl is a nice scripting language, but originally it wasn’t designed for the Win32 OS. There have been many improvements over time however (the greatest of them all being ActivePerl with PPM, which – as opposed to CPAN – doesn’t require you to have all those command line tools which you have on 99.9* on the *NIX systems, but you can only get it on Windows by installing several programs). Here are a few pointers for you if you are trying to make it work on Windows:

There is a dedicated subdomain on perl.org to the Win32 issues

Many Windows specific functions / methods do not set the $! or $^E variable correctly in case of errors, making debugging harder. In this case you can use the following construct:

use Win32::API;

...
warn (Win32::FormatMessage(Win32::GetLastError())) if (Win32::GetLastError());


Just remember to call this as soon as possible after the error, because other API calls may reset the value returned to 0 (which means no error).

If you are using ActivePerl, you should install alternative package sources. A great list can be found on the win32.perl.org wiki.

If you find modules on CPAN which are not present in the PPM repositories, you can try downloading the ZIP containing them and copying the directory structure manually to your Perl installation directory (of course you shouldn’t just copy all the files, but try to figure out which file goes where – this process is made easier that the ZIP / TAR.GZ file itself has a tree structure which is similar to the target tree structure). Many times this is all that it required to install a module. If you need a free solution to extract the files, try IZArc (now also with command line).

And one final tip: if you created a multi-threaded script with the threads module and it keeps crashing on you, make sure that all your accesses to shared variables are synchronized with lock. Because there is no explicit unlock command, you can use the fact that lock is block scoped and write the code as follows:

... not  synchronized code ...
{
  lock($shared_variable);
  ... synchronized code ...
}
... not  synchronized code ...

]]>
https://grey-panther.net/2006/12/perl-and-windows.html/feed 0 943