quinta-feira, 9 de junho de 2011

Patchguard red flags

Having a 64bit machine for a month now, and in need to perform some tests on Windows x64 kernel, I decided it was time to take on Patchguard(PG). I started by searching the Internet for ways to disable it, and to my suprise there was almost nothing up to date on the subject.
I did found one working patch on PG by Fyyre. Pretty awesome work, I'd say. Basically he says to look for cross references of InitSafeBootMode and patch the one he points as critical. I found it pretty simple to follow, and wondered how a multi-billion dollar product can be broken so easily.
So, I started looking for tips in code that could denounce PG hot paths, and I found one:

Looking for cross references of KdDebuggerNotPresent. There are a bunch of them, but restricting the search to the following operations you get the critical path that enables PG:
1. cmp operations,
2. followed by conditional jump,
3. followed by a unconditional jump to the it's own location, locking the cpu.

The only two functions that relate to this, are KiFilterFiberContext and KiEnablePatchGuard.
It is as Microsoft didn't want us to enter this functions with a debugger, which is understandable as that could compromise PG, but they should at least not leave this red flags behind.

segunda-feira, 6 de junho de 2011

Session wide shut

Or why you shouldn't leave your sessions hanging around. After having read about Pass the Pass, I decided to investigate it, to evaluate how deep my passwords could be compromised.
When I logon into a machine, Windows usually receives my user login and corresponding password.
Now, Windows has my credentials, and must validate them. As there are many authentication services out there, the folks at Microsoft decided, and very well (Linux also), make it a modular approach.
They ended up with a concept of an Authentication Module, who's responsible for establishing a secure connection with the server side of the authentication service, validate the provided credentials, and returning the result to the authenticator manager, performed by Lsass.exe process.
So far so good, what's the problem then? Well, besides validating the user, Windows also adopted some standards with the purpose to ease thing on users, like not having to carry around dozens of passwords, and not being constantly popped by login windows requesting for us to reenter those passwords.
Meet SSPI, or Secure Support Provider Interface, as Microsoft discribes it "allows an application to use various security models available on a computer or network without changing the interface to the security system. SSPI does not establish logon credentials because that is generally a privileged operation handled by the operating system."
With SSPI, Windows can log you in any service across your realm. It's sort of a universal security package that transparently crosses Authentication mechanisms without you noticing.
The hell begins, when Microsoft begins to provide support for protocols that need clear text passwords to properly operate, like Digests and Terminal services, WDigest and TsPkg security packages.
Lets begin by the user logging in then. Lsass.exe receives credentials by SspiSrv module and SspirLogonUser function. This function iterates all the registered authentication packages, maintained in pPackageControlList:

dc lsasrv!pPackageControlList
7537a484 0031af00 00000010 00000009 0031b020 ..1......... .1.

At 7537a484 we've got a list pointer to all the packages, and at 7537a484+4 the count of packages available.

dc 0031af00
0031af00 00300238 00300618 00301128 00316378 8.0...0.(.0.xc1.
0031af10 0031d5d0 0031d6ac 0031e428 00321580 ..1...1.(.1...2.
0031af20 003216e0 003217e0 00000000 00000000 ..2...2.........

dc 00300238
00300238 00000000 00000000 00000014 00083bb3 .............;..
00300248 00000009 00000001 00002fe0 00000000 ........./......
00300258 00000000 00000000 00140012 002f6398 .............c/.
00300268 003a0038 002f3b20 00300220 00300320 8.:. ;/. .0. .0.

dc 00300618
00300618 00000001 00000000 00000016 00113913 .............9..
00300628 0000001e 00000001 00002ee0 00000000 ................
00300638 00000000 00000000 001a0018 002ff9f0 ............../.
00300648 003c003a 002f3c88 00300600 00000000 :.<..

ddu 00300220
...
0030022c 002f3a48 "C:\Windows\system32\lsasrv.dll"
...
00300264 002f6398 "Negotiate"
00300268 003a0038 ""
0030026c 002f3b20 "Microsoft Package Negotiator"

ddu poi(poi(0031af00+1c)+38)
...
00321574 0031ade0 "C:\Windows\system32\tspkg.DLL"
...
003215ac 0031e998 "TSSSP"
...
003215b4 00306180 "TS Service Security Package"
...
003215cc 0031ae28 "C:\Windows\SysWOW64\TsPkg.DLL"

As it goes thru all the packages, it passes the credentials to them, one by one. The security package has now the opportunity to do whatever it wants with the credentials, and as I said before, some of them decide to keep a copy of it. The interface provided is SpAcceptCredentials. Analyzing it's parameters:

dc esp
00bcef04 752a77e0 00000002 00bcefcc 0032b830 .w*u........0.2.
00bcef14 00bcef44 00000000 00bcf0c8 003ae2e0 D.............:.

dc 00bcef44
00bcef44 001ffcf2 00000000 001a001a 00362218 ............."6.
00bcef54 000a000a 00385b30 00160016 003a6bc0 ....0[8......k:.
00bcef64 00000000 00000000 00362538 0a000001 ........8%6.....

dc 00362218
00362218 00640041 0069006d 0069006e 00740073 A.d.m.i.n.i.s.t.
00362228 00610072 006f0074 00000072 00000000 r.a.t.o.r.......
00362238 363df430 88000000 00000000 00321f48 0.=6........H.2.

dc 00385b30
00385b30 006d0076 00300030 00000031 00000007 v.m.0.0.1.......
00385b40 363c3c1f 8c000220 006d0076 00300030 .<<6 ...v.
00385b50 00000031 00000000 363c3c1c 8a000074 1........<&lt

dc 003a6bc0
003a6bc0 00XX00XX 00XX00XX 00XX00XX 00XX00XX X.X.X.X.X.X.X.X.
003a6bd0 00XX00XX 00000021 36eb697c 88000000 X.X.X...i.6....
003a6be0 004b0050 00530043 00370020 00440020 P.K.C.S. .7. .D.


We've got the login, the domain and password. Truth be told that, at least, the credentials don't lay around in the clear, they are protected by usage of the known LsaProtectMemory. But this "protection" becomes just an obfuscation technique.

Pass the Pass, the name given to the extraction process of user passwords, shares the same roots as it's homologous, Pass the Hash.
Pass the Hash uses the LM an NTLM hashes retained by the msv1_0 security package module.
These hashes are used as authentication tokens to any other machine that recognizes them as valid mappings to authenticated entities.
As Pass the Hash is around for many years now, so will be Pass the Pass.
So, the problem as I see it is unsolvable, except if SSPI is accepted as a optional feature, and the user is given the chance do disable it.

But not all are bad news, the credentials are there but only for the lifetime of the opened session. Shutdown your sessions as soon as possible and you won't be having passwords lingering around.

quarta-feira, 1 de junho de 2011

Theory of conspiracy, secret codes in .NET exceptions

Ever noticed those weird values in .Net exceptions that get into RaiseException native call?
There's 0xE0434352 for CLR4 and 0xE0434F4D for CLR2.
.formats 0xE0434F4D
Evaluate expression:
Chars:   .COM

.formats 0xE0434352
Evaluate expression:
Chars:   .CCR
.COM? They really have a sense of humor.

sexta-feira, 20 de maio de 2011

Reversing a reverser

Two weeks ago, when I finally managed to get a 64bit machine and migrate to a 64bit OS, I installed for the first time Windows 7 64bits. Installation of a new OS is a terrifying experience, specially when moving to a new platform, some software that we're used to, ceases to function correctly, we need to reinstall tons of software, some we forget, some are no longer available. I think everyone has gone thru the process at least one time in their lives.
So, I was installing the tools of the trade, IDA being one of them and one of my favorite tools ever. As soon as I started IDA, I noticed that it failed loading the symbols of the target PE/PE+ file. What was going on? I reinstalled the tool, installed Microsoft debugging tools, and the symbols were resolved with Windbg but not with IDA.The weirder part of it, was that IDA was still asking me if I wanted to load the symbols, and yes, I answered affirmatively.I started debugging symbol loading, and everything worked fine. The problem was just within IDA.
I activated logging in symbol load, and I got this:
DBGHELP: new session: Thu May 19 16:11:28 2011
DBGHELP: Symbol Search Path: ¸Û¾
DBGHELP: No header for C:\Users\popo\Desktop\win7x86\logoncli.dll.  Searching for image on disk
DBGHELP: C:\Users\popo\Desktop\win7x86\logoncli.dll - OK
DBGHELP: ¸Û¾\logoncli.pdb - file not found
DBGHELP: ¸Û¾\dll\logoncli.pdb - file not found
DBGHELP: ¸Û¾\symbols\dll\logoncli.pdb - file not found
DBGHELP: C:\Users\popo\Desktop\win7x86\logoncli.pdb - file not found
DBGHELP: logoncli.pdb - file not found
DBGHELP: logoncli - export symbols
DBGHELP: closing session: Thu May 19 16:11:28 2011
The symbol search path had a weird string value. I checked the environment variables , and again everything was fine. I was irritated by now with IDA, because being such a great tool I couldn't get any clue of what was going on.
I searched all over the Internet and there was no answer for this problem anywhere, no clue in Hex-Rays blog. What the hell? Is it only me?
I started manipulating pdb.cfg and again, nothing.
One thing though that I noticed was that the symbols files were loaded if in the same directory than the object file, so for the first week I managed to go along by loading manually the .pdb and then copying it to the same directory of the executable.
Yesterday I asked myself, I'm I a reverser of a mouse? So I dug into reversing and debugging IDA.
This is what I found.
By the time IDA tries to initialize the symbols, the search path is corrupted. So I backtracked were was the path being set. This block of code tries to start-up a couple of components, and for the code to get the right values from _NT_SYMBOL_PATH or _NT_ALTERNATE_SYMBOL_PATH , it needed to successfully create one of this COM objects.
After getting the class ID of the COM object, all I needed to do was to go to my old XP and find out which executable file was being started.

The executable I found was a .dll file called msdia90.dll. All that's left to do is to grab this dll, copy it to my new machine and register it within the system:
regsvr32 msdia90.dll
And finally IDA worked its magic as always. Hurra!!...

quarta-feira, 18 de maio de 2011

Robbing sessions

What happens when the system trusts certain kinds of users? You can steal remote or local sessions. This post intents to demonstrate a local session assault as a PoC. More details will be given if you wish to escalate the technique :). Keep in mind that although this discussion is applicable to XP family, I'll be just talking about what happens in Windows 7 and 2008.
So, when we're switching between session in a Windows machine, thanks to Remote Desktop services and/or Fast User Switch, lsm is notified about our intents and haply, if we present the credentials of the user who owns the targeted session, switches us to the intended session, and locks our old one.
This is what the api tells us, but in practice there is more about it. LSM misbehaves and as you can see from the picture, before validating the password it checks the caller credibility.

So how can we bypass this check, just by injecting into our own winlogon process, who is a trusted caller, and that's running in our same session, so no need to cross sessions tricks.
I built a tool for a simple demo called rob console, this tool simply switches you to the first login session you made into the machine, without requesting for a password. Keep in mind that you need to be an admin to call the tool. The tool runs only in Windows 7 32 bits.
To see it in action do the following: login to your machine, your first session will open and this will be the session you will be robbing. Go to the your 'Start menu' and choose 'Switch user', login again, this time with your admin account, run the tool and voilá.
Please note that the tool connects to session 1, if you happened to logoff from any previous session the tool will fail the switch, because session 1 will not be available any more.
To see if session 1 is still around use the following command:
 
query session

SESSIONNAME USERNAME        ID  STATE   TYPE DEVICE
services                     0  Disc
console      popo            1  Active
             Administrator   2  Disc
rdp-tcp                  65536  Listen
If session 1 is no longer, than you need to reboot the machine in order to reset the session counter.
Now that you know the music let's dance the tango, cute things to do: remote session stealing - as soon as you connect remotely, even without logging in, a session will be created, this opens the chance to steal any remote session without the need to formally establishing the logon session with all the extras, drive mapping, user env., etc.
Combine this to elchomp, and you have an attack without forensic trail. Everything is done by the user, only the user, and nobody else but the user.

Enjoy.



segunda-feira, 16 de maio de 2011

Unlocking the Windows Station

Ever wondered why you shouldn't leave your computer with your session opened while the screen is locked?
This hazard falls in several OS domains if you consider the various types of attacks available out there.
This one in particular is focused on Windows, so if you're a Windows fan keep reading.
As far as I remember, at least since XP, this approach has been possible, although not wildly publicized. The "attack", consists just in injecting code in a cross-session Winlogon privileged process, that's retaining the desktop hidden. For this we need two things: remote or local access to the machine, (although local should be locked :)), and a privileged token, so we can cross session boundaries.
So, if we're already the machine's owner why do I call it an "attack"? Instead of forcing myself into the user locked session I could just patch the machine's code and collect every info I'd need like passwords, etc.
Well, that's true, but consider the amount of noise you'll make, the forensic trails you'll leave and consider your physical location. If for example the machine is network locked out, your only chance might be to use a USB or firewire local attack, and grab immediate access to an open domain session. If lucky could be the domain admin.
Besides, it's much funnier seeing CEOs faces when their sessions are opened wide.
Why is it an hazard? because everything becomes available to the intruder, private cache, private certificates, protected storage passwords, EFS files, etc. Not a pretty sight.

The tool is available here: https://www.filesanywhere.com/fs/v.aspx?v=8b6d698c615e76b4a2ab
To setup things you should remotely access the machine with administrative rights, copy unlockcon.exe to a folder, select the appropriate Win7 OS type, rtm or sp1, and copy the newdll.dll to the same location as unlockcon.exe.
Now, all you need is run it, and watch it do it's magic.

If you don't have two computers, then try this, create a batch file called unlock.bat and add the following commands to it's content:

timeout /t 30
unlockcon.exe

run the bat and lock the desktop. wait for 30 seconds and voilá...

nice trick to play with your friends.

How does it work?
Winlogon since Windows 7, is a state machine, that keeps track of it's interaction with the user, this state is recorded in an exported symbol xGlobalContext. When following winstation unlocking process, it ends in WluiReleaseUI, which is the crucial part of the process that unlocks the screen. See also WlAccessibilitySwitchDesktop and WluiAbort.

One final note: this tool doesn't reset the Winlogon state machine state. So, you won't be able to lock the desktop back to it's original look and feel. Instead, you can manually do it yourself by going to the start menu and in the shutdown button, click 'switch user'. (hint for a reverser who want's to code it's own fully functional tool).

Hope you liked it

Next post will be about session stealing, remote and local.

quarta-feira, 16 de março de 2011

Windows 7/2008 Event Log forensic and reversing analysis

eseugutroP Reversed by ar1vr


This text refers to the 32bit version of Windows, unfortunately I don't have access to a 64bit development environment.

Opening an .evtx log is pretty straightforward, the only problem is that the eventlog service opens this files exclusively and if we try to make a copy, we'll get "Access is denied" error. So, we need to get them with the machine offline.

One of the reasons beyond the handles to this files being exclusively open, is that the eventlog service memory maps chunks of this files, holding and manipulating some housekeeping metadata information directly in the memory mapped files.
Performance and security issues also come to the discussion: the files aren't always in sync with the data in memory for example, and each file has an associated timer that CRCs the headers and flushes the mapped views. Also this metadata information allows for file recovery in case of unexpected shutdown or crash.


Figure 1: Event log layout


What this means for a "interested" person, is that we need to be careful if trying to change the logs content online, because not everything is what it seems. But it is indeed possible to manipulate the logs directly in the eventlog service: remove and change log entries, insert new entries, stealthily clear the logs, add log garbage, etc. without restarting or shuting down the service or the machine.
I wrote a small POC tool that shows this being done, I called it Elchomp. Elchomp basically clears the last log record entry in the event log of choosing. You can download Elchomp at the end of this post.

The .evtx files are binary files, to where the eventlog service streams log records using XML templates to format each entry. This makes easier switching between the Event Viewer general and details panels.
These binary files are structured as follows:
- The file starts with a file header that describes the chunks used by the file. The stored information pertains to the number of chunks, the chunk size, and some duplicated information for failover purposes. A chunk is a container block of event records.
- N Chunks serialized. Each chunk points to a set of event log entries.
- N records. Each record represents an event log entry.

Let's view in more detail each of these structures. I'll cover only the most important data, so keep this in mind while reading. I'll open a real .evtx log for analysis. Figure 2 shows the first bytes of the file.

As can be seen, there are a couple of signatures in the file, the first signature "ElfFile" at position zero in the file, marks the beginning of the file, and is used to detect if this is an event log file type.

Figure 2: File Header


At offset 0x10 we have the CurrentChunkCount. This DWORD value doesn't show up in the eventlog file, I just mention it here because I wanted to enforce the differences between the offline and online layouts. When the log is opened by the eventlog service, the CurrentChunkCount is set to the chunk that the NumberOfChunks references, a new chunk is created and the ChunkOffset is updated accordingly.
At offset 0x28, NumberOfChunks, a WORD value, indicates how many chunks are in the file.
At offset 0x30, SizeOfHeader a WORD value, sets the size for the file header.
Positioning to the end of the File header, value 0x1000, we can see the first chunk signature. (Figure 3)

Figure 3: First Chunk

It's time to say that the chunks are fixed sized 0x10000 = 65536 bytes. The last chunk is always memory mapped in the eventlog service process.
Multiplying size of chunk by NumberOfChunks we get 0x10000*0x001d = 0x1d0000,
sum the FileHeader and we get to last valid chunk header: 0x1d0000+0x1000 = 0x1d1000. (Figure 4)


Figure 4: Last Chunk Header Data


"ElfChnk" at position zero in the ChunkHeader, validates the chunk beginning.
At offset 0x10 and 0x20 we've got the same value, for failsafe purpose. It's a DWORD (0x00000e15) that represents the number of records contained in the chunk. Actually, if a new record is written it will use this value as Record counter, so the Number of records can be calculated by subtracting one to this value.
At offset 0x30 a DWORD that indicates the last offset position in the chunk that can be written to.

Figure 5: Last valid position in log


LastChunkStart = 0x001d1000
LastValidOffset = 0x000066b8
LastValidPosition = 0x001d1000 + 0x000066b8 = 0x001d76b8

From position 0x001d76b8 forward, there are only zeros. (Figure 5)

The last valid position also gives us the last valid record end. going backwards, we reach the signature (position 0x1d7438 in figure 6) for the last event record '**' or 0x2A2A.


Figure 6: Event Record Data

At offset 0x6 we find the current record count 0xe14 (being this the last valid record in the chunk this value is equal to the chunk's number of records minus one).
At offset 0xe and 0x86 the timestamp in file format. Corresponds to the event viewer's "Logged" time field.
At offset 0x7a the Event Id.
At offset 0x7e the Keywords field.
At offset 0x96 the record Id.
At offset 0x9e the SID.
At offset 0xda we've got the log message.

Figure 7: Event Viewer log entry

Hope you enjoyed

ElChomp is available here https://www.filesanywhere.com/fs/v.aspx?v=8a6b66865967747da3a5

You need to run the tool with UAC elevated administrator token in order to successfully eat the last log entry.



How does Elchomp works?

At the base core of Event log service is the wevtsvc.dll dll. Wevtsvc keeps track of the log files using a global variable called LogFilesHead.



x wevtsvc!LogFilesHead
6bfb6130 wevtsvc!LogFilesHead = <>

You call walk this list, and see which log files are registered:

r $t1=poi(6bfb6130); .for (r $t2=1; @$t2 < 9;r $t2 = @$t2+1 ) { du poi(@$t1+c)+8; r $t1=poi(@$t1); } 00bd7658 "Windows PowerShell" 005f85a8 "System" 005f8800 "Security" 005f8a58 "Media Center" 00bd60c8 "Key Management Service" 00bd7348 "Internet Explorer" 005f88e0 "HardwareEvents" 00bd08e0 "Application"

At 0x98 offset from the LOG_FILE struct, we get to the FILE object:

r $t1=poi(6bfb6130); .for (r $t2=1; @$t2 < 9;r $t2 = @$t2+1 ) { dd @$t1 l1; r $t1=poi(@$t1); } 005fe410 005f9130 005f9130 005f8fa0 005f8fa0 005f8da0 005f8da0 005f8bc8 005f8bc8 005f8a80 005f8a80 005f8820 005f8820 00bd0820 00bd0820 6bfb6130

dd 00bd0820+98 l1
00bd08b8 0036db20 <--- File Object dc 0036db20
0036db20 6bfb6108 003835f8 0048f2bc 00000000 .a.k.58...H.....
0036db30 00000000 00000009 46666c45 00656c69 ........ElfFile.
0036db40 00000000 00000000 00000000 00000000 ................
0036db50 00000e68 00000000 00000080 00030001 h...............

ln 6bfb6108
Exact matches:
wevtsvc!FileTrackHeader =

Now what? As the Wevtsvc is build in C++, we need to respect object hierarchy and follow its rules to facilitate getting the object pointers we’re interested in.
Lets introduce ChannelManager. ChannelManager is a one instance object that manages communication channels between logs and subscribers, it keeps record of open logs, starts and stops event, enforces policies, etc. ChannelManager is available at the wevtsvc!gChannelMgr.

Each log file is tracked by ChannelManager, using a File RTTI object. To get to a specific object File, we need to call ChannelManager::GetChannelFile using the name of the log we’re targeting.

The FileObject is composed of a WriteFileView object, a pointer can be referenced at offset 0xF8. Using this WriteFileView object and calling the method WriteFileView::GetBufferPtr we finally can position ourselves to the Chunk buffer covered before, as you can see, we’re getting the chunk signature. This mapped Chunk is the last Chunk on the file. If you need to walk backwards and map any previous Chunk, File::MapInNewWriteChunk, is the right function for you.

001bdbe0 43666c45 006b6e68 00000001 00000000 ElfChnk.........
001bdbf0 00000006 00000000 0000000c 00000000 ................
001bdc00 00000011 00000000 00000080 00000ac0 ................
001bdc10 00000de0 06a174ed 00000000 00000000 .....t..........
001bdc20 00000000 00000000 00000000 00000000 ................
001bdc30 00000000 00000000 00000000 00000000 ................
001bdc40 00000000 00000000 00000000 00000000 ................
001bdc50 00000000 00000000 00000001 7b1dda33 ............3..{

So in order to alter the event log state we need to change the Chunk contents, and we need to update some metadata in the RTTI File Object.
Most important attributes to change for a successful update (the names are based on their purpose):

File::RecordCount (Offset 0x30)
File::PreviousEventPublisherRecordNr (Offset 0xF0)
File::LastValidOffset (Offset 0x130)
File::SaveToFileFlag1 (Offset 0x10)
File::SaveToFileFlag2 (Offset 0x330)

As Elchomp is a PoC, I don’t deal with concurrency, so it might crash the eventlog service. This is no big deal as you can restart it again, but don’t tell that I didn’t warn you.



Hope you enjoyed