Sunday, January 15, 2006

There are several options if you are looking to create a firewall. This list is by no means complete, just as a reference for myself basically : )

 

1. NDIS driver (Protocol - implements a protocol, Intermediate Level - can do filtering,translations, and packet scheduling and Miniport drivers - the final level that actually talks to the nic) - Best but most difficult

2. TDI filter driver - decent, can be circumvented via RawIp

3. Layered Service Provider - can be circumvented easily.

4. Winsock Hooks (pain to implement, can be circumvented fairly easily)

5. Filter-hook driver (only one allowed on a system - if another app uses it - you are out of luck) Cant access data

uses IOCTL_PF_SET_EXTENSION_POINTER with IoBuildDeviceIoControlRequest();

6. Firewall hook driver (relatively undocumented way -  see http://www.codeproject.com/internet/FwHookDrv.asp) Not recommended by MS. More difficult to modify data than TDI as its pretty undocumented

From Microsoft:

It is not recommended to implement a firewall-hook driver (or firewall driver) for Microsoft Windows XP and later versions of the operating system.

The Microsoft Windows 2000 DDK introduced the concept of a firewall-hook driver. The intent of a firewall-hook driver was to manage network packets that were sent and received across a firewall in the context of the TCP/IP protocol. A firewall is a control system that prevents unauthorized users from gaining access to a local network that is connected to the Internet.

A firewall-hook driver did not meet firewall requirements because it ran too high in the network stack. A firewall-hook driver could also interfere with the operations of Internet Connection Sharing (ICS) or a personal firewall implementation.

To provide firewall functionality on Windows XP and later, you should create an NDIS intermediate miniport driver to manage packets sent and received across a firewall. For information on creating an NDIS intermediate miniport driver, see NDIS Intermediate Drivers.

1/15/2006 8:00:44 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Friday, January 06, 2006

I've decided it's time to fight back and provide some tools for people to fight malware.

The first step to fighting it on your machine (this article is geared to the more technical crowd) is being able to stop it from loading, replicating, and communicating.

1. Always review your firewall rules.

2 . Process Creation

 

NtCreateSection

MiFindImageSectionObject

MiLockPfnDatabase

MiInsertImageSectionObject

MiCreateImageFileMap

NtCreateProcessEx

MmCreateProcessAddressSpace

MmCreatePeb

BasePushProcessParameters

BaseCreateStack

 

1/6/2006 10:45:53 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Im working on a new utility to help systems guys fight spyware on their systems. I was quite frustrated trying to get one off my Mother's machine, random named exes would keep appearing, even after safe mode boots and removal of hklm\software\microsoft\windows\run keys. I tried also 'pausing' the process using process explorer from sysinternals with limited success. So.. now Im writing a kernel mode driver to help combat this.

For starters, lets visit the short list of how all things can load on the system.

 

ShellExecute Hooks
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks

Shell Delay Load Objects
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ShellServiceObjectDelayLoad

URL Search Hooks
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\URLSearchHooks

App Init DLLs
HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Windows, AppInit_DLLs

Download Manager
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer, DownloadUI
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer, DownloadUI

Notification Packages
HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\CurrentVersion\Winlogon\Notify

 

User\Start Menu\Programs\Startup;
All Users\Start Menu\Programs\Startup;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run;
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce;
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices;
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnceEx;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon, Shell;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon, System;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon, VmApplet;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon, UIHost;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon, Userinit;
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows, run;
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Windows, load;
HKEY_LOCAL_MACHINE\Software\Microsoft\Active Setup\Installed Components;
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager, BootExecute;
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows CurrentVersion\Explorer\BrowserHelperObjects
win.ini, load;
win.ini, run;
system.ini, shell.

They can also install themselves as services:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services

All of these locations can be exploited.

1/6/2006 12:07:58 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, January 05, 2006

So Im trying to compile a kernel mode driver I'm writing against the ddk rather than using vs.net.

First off, to use visual studio, read:

http://tiger.la.asu.edu/Quick_Ref/DeviceDriver.pdf

as well as there is a nice batch at http://www.osronline.com/article.cfm?article=43

but everyone says "hey - use the ddk - that what the compiler is there for"

Ok, so I keep getting an error on this line.

PHYSICAL_ADDRESS    PhysicalAddress; <-- error here -

PhysicalAddress = MmGetPhysicalAddress((void*)block);

 

error:

 error C2275: 'PHYSICAL_ADDRESS' : illegal use of this type as an expression

hmm... its used throughout the ddk samples that I can build. So I try PVOID, void*, ULONG all with the same result.

Then it occurs to me - the types are recognized, how about moving the defs to the top of the procedure (sorry - I've been so used to modern compilers

where you can gladly declare vars anywhere) and voila. Thats an hour of my life I'll never get back - thanks ddk guys for packaging that wonderful compiler with the ddk!!

 

 

1/5/2006 11:56:31 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, December 28, 2005

Sometimes there is a need to control when a page is accessed through a link and bookmark it. For instance,

your company sells a product that should only be valid for a certain time, or provides access to a special deal.

Every page then needs to include checks to determine if the item in question is valid or not.

ex.

www.secure-coding.com/ProductDetails.aspx?id=68

So a check needs to be made to the database, requiring an extra hit on what may be an already busy system.

If you have items that expire quite often, here is an alternative:

www.secure-coding.com/ProductDetails.aspx?id=68&expires=12282005

Now this is quite obvious of course on how one can get around that. However, encrypting it becomes:

www.secure-coding.com/ProductDetails.aspx?54754a68666e3839467646496659745a7467574750773d3d

A page can then determine if the access is still valid.

Still yet another usage

www.secure-coding.com/Admin/DeleteItem.aspx?id=68

Two scenarios can occur, if you use the querystring to manage items in a database, its quite easy to select the wrong one in your recent history.

One alternative is when a link is generated to DeleteItem.aspx, generate a timestamp. If you use a common page baseclass, then that baseclass can decrypt the querystring and check for an expiration date. If it has expired, the user can be redirect, etc.

Once again I advocate encrypting the querystring. I love it : )

Yes - this can be attacked, as can just about anything - but provides an extra layer of data protection and a means to timestamp your links.

This is especially useful when users have very old links they bookmark and you want an easy way to check the lengths of time users keep old links, and refer them to new/updated links.

 

 

 

12/28/2005 5:26:58 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback

Heres just a quick list of tips I tell people

1. Dont use embedded queries, use stored procedures, avoid sp_executesql

2. Remove all < > -- ' / \ from input strings. You will need to write a loop that filters multibyte sequences after single byte sequences and loops until no more can be found. Because for ex.

hello-/-john

if you remove the / you are left with hello--john, and thats a problem.

3. Refilter ALL input, including querystring. If you provide a link www.somesite.com/products.aspx?id=906B

Assume someone is messing around with the url and trying things like

www.somesite.com/products.aspx?id='--

to test for sql injection attacks.

4. Make sure your login pages are https. I know - seems like a given, however many sites actually have login pages that are not https, but post to https pages, hence the data is still secure.

However, the 'lay user' doesn't see the little 'secure' lock in their browser and don't think it is secure. Believe it or not I've heard quite a few complaints from users trying to access sites in that manner.

5. Encrypt all query string information - I should be posting some code shortly for this.

6. Configure error pages for all of your applications (in turn make sure your <customErrors> section in web.config is set to RemoteOnly so remote users wont get asp.net error messages.

Catch errors in global.asax application_onerror and log your errors at least to a file. If you log to the event log, remember to give asp.net permissions to the eventlog registry key

http://support.microsoft.com/default.aspx?scid=kb;en-us;329291 (I believe if you give aspnet (2000,xp)/network service (2003) permissions to

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application

you should be ok. Log to a file first, since that is the method most likely to work. If you log to a db and that fails, your code needs to continue logging, hence easiest to log to a file first. TEST THIS for every application you deploy.

 

 

 

12/28/2005 12:33:11 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Wednesday, November 30, 2005

From a local machine, it seems maxing out your network connection can cause a terminal service session to disconnect.

From there, its a small step to enumerate connected users, hammer them and use up available sessions.

Only solution I can think of is qos packet scheduling. I'll have to investigate this one further.

11/30/2005 4:26:30 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, November 15, 2005

Nice work on the automatically generated code for the login component -

If you name your page login.aspx and put a login control on the page, it seems theres a namespace problem and the code casts to a (Login) control, which really casts to your page class - hence the problem, because it's expecting a Login control instead. Solution is to rename your page class.

1. Rename your page to AccessLogin.aspx for example

2. Rename (right click on it and select refactore-rename for best results) your class in your code behind from Login to AccessLogin

3. Update your "Inherits" tag on your .aspx page from Inherits="Login" to Inherits="AccessLogin"

That should do it.

11/15/2005 11:11:05 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Thursday, November 03, 2005

Be careful of embedding script in server controls, it won't work and can very well lead to information gathering.

This is of course a very simple example. Code is not processed in this case:

<asp:HyperLink id="HyperLinkStatement" NavigateUrl="MyUrl.aspx?<%=GetSecureInformationFromEncryptedFile("c:\\somefile.txt")%>" style="Z-INDEX: 101" runat="server">Download</asp:HyperLink>

This will not evaluate the method. I always find it interesting the results you get when searching for asp code on the net. Because of misconfigurations or server migrations, you can view the entire source code for various sites out there.

11/3/2005 10:23:06 AM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |  Trackback
 Tuesday, October 25, 2005

Accessing a remote resource

First understand the difference between LOGON32_LOGON_INTERACTIVE and LOGON32_LOGON_NETWORK

Second understand that if:

1. You are on a machine (Machine A) that is not part of the domain

And

2. You are trying to access a domain machine (Machine B) using domain credentials from Machine A using LogonUser

This will not work. Machine A doesn't know about this domain, so getting a token with information for some domain that is unknown is useless.

You must be using a domain account. One mistake that is quite common deals with a misunderstanding about logging on users. If I make a call to LogonUser and specify LOGON32_LOGON_NETWORK, there is a search order for domain controllers to validate that name. If you have specified the local machine, then there is no validation unless of course you are on a domain controller. If you are trying to validate against another machine on the network that is NOT PART OF A DOMAIN - you cannot validate these credentials through logonuser. You must map the connection as described below. Even if the local login and password match that of the remote machine, this will not work. It can be confusing, because if I try to access machine b from Machine A, and they both have an administrator account with a different password that I need to specify in the credentials from machine a:

MachineB\administrator

in order to validate the user on machineb. So one would think I can call logon user and specify a remote machine name. False. You cannot (as far as anything I am aware of). So then how does Windows do it you say, or such things like runas.exe? Think what happens in a remote machine network access. Your system tries to setup an SMB session. The remote server requires more information and sends back STATUS_MORE_PROCESSING_REQUIRED. Your system sends over the appropriate authentication information. You then access the interprocess communication share at \\MachineB\IPC$ and once this is established (with a proper account) can perform your network request (ex. c:>dir \\machineb\someshare)

How can you then achieve this behavior? Simply enough, in this case you use the WNetAddConnection2 api to establish a session to \\machineb\ipc$. Once that session is established you have "remote permissions" for your current login and can then do your mojo. You are using SMB session information, and not logonuser to achieve this.

 

10/25/2005 8:19:08 PM (Eastern Standard Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  |  Trackback