start	end	text
0	4560	It will just be a minute more as we get self-paced running and things like that in our presentation.
6300	10700	The presentation was originally developed for an hour and 30 minutes.
10800	16180	However, this time slot is an hour and 50, I mean 50 minutes and we've already filled like 7.
16700	22040	Therefore, we may run a little bit late if we need to leave early.
23900	28520	However, I will go through the first 20 slides in about 2 minutes
28520	31480	because we don't have time to get them in.
31520	36860	And Sherry does the interesting slides, so I will introduce her soon.
37000	40400	My name is Jamie Butler. I'm from Rootkid.com.
40400	42080	This is Sherry Sparks.
42140	47780	And we're developing a project called Shadow Walker and it's to hide rootkits.
48300	53580	You can find a description of this talk probably later on Rootkid.com.
53580	55840	It's in the source code. I believe Sherry has proposed it.
55840	58580	Also, it will be in FRAG 63.
59200	64160	If it hasn't appeared online already, probably in the next week or two it will be there.
64180	70260	If you don't understand much about rootkits or you are new to the Windows world of rootkits,
70260	72020	you can go to Rootkid.com.
72020	76300	We post what's there for free and there's a lot of source code for free.
76640	79120	Nothing there is for free.
79120	86580	Or you can apply for a rootkit supporting the Windows kernel by Greg Kogel and myself.
87100	88980	So we'll get started with Shadow Walker.
92820	94540	So a quick flow through.
94620	98100	Rootkits, they don't propagate themselves. They're not like a virus.
98100	99760	They're just here to provide stuff.
99860	103960	So the attacker gets on the box and they try to maintain presence.
104040	108160	They don't want to keep using their zero day to come back all the time to the machine.
108160	109920	So they install a rootkit.
110060	116440	A rootkit is there to hide their presence and also to give them future access at a later date.
116760	123840	Rootkits can also be used for law enforcement for things like a sneak and peek or a properly executed search warrant.
124640	131320	There's two levels of protection within the Windows and Linux operating system.
131320	134660	There's basically two rings, ring 0 and ring 3.
134660	140260	Ring 3 is user land processes. They are unprivileged.
140260	141960	Ring 0 is kernel land.
142420	147760	Once you're in ring 0, your kernel rootkit can do whatever you want.
148820	159980	Operating system provides basically an intermediary between upper level user processes and things that they want to query the operating system for.
159980	162420	So I want to open a port.
162420	164340	The operating system does that for you.
164340	167360	And then hands it back to the user land process.
167360	173860	They also provide an interface between user land processes and the lower hardware.
174180	181320	So if you have a ring 0 kernel rootkit, you are just like the operating system, you are a man in the middle.
183700	189800	Some of the different OS components that a rootkit may want to attack would be the IOManager.
189800	191680	You can install keyloggers.
191820	196920	Sharing has a project on rootkit.com that's a keyboard sniffer.
197400	200040	And you can also attack the file system.
200060	206700	You can return file filter driver and interface between every single access of the hard drive.
206700	214560	The object manager has things like processes and threads that it uses to keep bookkeeping.
214620	220400	And you can attack the object manager in order to hide your processes and threads.
222420	224900	That's enough of that configuration manager.
224900	226640	You can use that to hide registries.
226760	229500	So first generation of rootkits, what were they?
229500	235320	These were simple infringement replacement programs on the hard drive.
237060	244360	They may include the Unix login program, LS, ES, so on and so forth.
245040	247160	Second generation rootkits.
247160	249720	These started to be more sophisticated.
250220	256740	These modified static tables within the kernel are within the upper levels of the operating system themselves.
256740	265600	So you can replace the import address table of a PE file and alter the execution path of any command.
265600	276900	You can also alter the system call table within the kernel and ring zero and change what function actually gets executed within the kernel when the user requests it.
278840	281560	Third generation rootkits.
281560	288260	We term these... they use DCOM, direct kernel object manipulation.
288540	293940	These actually don't hook anything because hooks are a bit easier to detect.
293940	298380	Third generation actually manipulate the data structures in memory.
298380	304900	So there's no code... you don't alter the code at all, you just alter the data structures themselves.
305000	307260	This is almost undetectable.
307260	310880	Data structures come and go very frequently and they're constantly changing.
310880	312880	That's why they're in the data structure.
314900	317460	This is very hard to detect.
317460	320960	And we'll talk about how you can use this to hide processes and threads if you wanted.
321080	327980	Or you can use it to hide drivers, escalate process privileges using tokens, etc.
329060	337200	So real quick, about two years ago at one of the black ads, and all the slides are online, you can see process hiding with DCOM.
337200	340080	I also mentioned a little bit last year when I talked about Python.
340960	347460	What the kernel uses to keep track of all the processes is this list of active processes.
347880	353220	Every e-process block you see there represents an individual process in the system.
353500	356760	This individual process could be your little hacker program.
356960	360860	It's doing things and you don't want the system administrator to know you're there.
361580	366880	If you simply unlink... at the bottom of the slide you see that there's a series of links.
366880	373760	If you simply unlink a process that you want to have hidden, it will disappear when you try to list it out.
374100	377900	So when you run task manager, etc., it won't be there.
380420	384740	Now, current rootkit detection methods, there's basically four types.
384740	386680	You don't have time to go into all these.
386820	391640	But just quickly, behavioral, integrity, signature-based, and difference-based.
392560	396720	Some of the AB products are basically an example of signature-based.
396740	404820	Integrity checkers, such as tripwire, check some of the disk files so that if you replace it with a fresh one, you'll be found.
404960	407440	Difference-based approaches is kind of a new thing.
408080	411980	Microsoft's doing it. F-Secure's doing it. Sysinternals.
412320	418200	What this is, is it does some kind of low-level scan within the kernel by following structures directly.
418200	422540	It tries to get a list of things like files and processes, registry keys, etc.
422840	425060	Then it does an upper-level API call.
425060	427500	If there's a difference, it knows something's up.
430580	431880	Behavioral detection.
432420	435800	In this, you try to detect the presence, the effects of rootkit.
435800	442920	So you might want to look for alteration in the execution path, or what is actually executed within the program.
442920	445600	Some of the system calls, or the ordering, etc.
446080	448780	We don't have time to go into more of that.
448800	451300	Integrity checking, exactly. It's a CRC.
451380	453340	This could be on-disk or in-memory.
453380	455960	However, hardly anyone is doing it in-memory.
457260	465380	Signature-based scan memory or on-disk for a particular set of bytes that represents the mal code.
467440	472180	So, we have a really powerful way to hide rootkit, or hide processes, etc.
472180	475100	within the kernel by modifying all these data structures.
475840	482780	However, if you look for our driver, because we are in the kernel, so we have a kernel-level driver,
482780	488340	you can just do a simple scan, like a signature scan, for the presence of the malware.
488860	491020	And that's not very good.
491360	496220	So what we want to do is to try to shake it up, so even if you scan memory,
496220	501520	you can't detect all that decomp stuff that's in here in the fu-rootkit.
502520	506720	You want to make it so you can't detect our rootkit within the kernel.
507140	511300	So, this is a problem that viruses have faced for a long time,
511300	514360	and they use things like polymorphism and stuff to get around it.
514640	522100	However, in the kernel, it gets more problematic to do really good polymorphism code.
522100	530280	Also, no one's doing it other than a holy father and his hacker defender.
530480	532680	And you have to get him to handle that.
533020	535840	And I think it's like 40 heroes in the county does it.
536380	543460	So, really quickly, we're going to walk through how we deploy this in memory and share it with people.
549910	551270	Thank you, Jamie.
551270	556530	I'm going to be discussing the technical implementation of ShadowWalker,
556530	559370	which is our rootkit hiding technology.
559690	565130	Like Jamie said, polymorphism has not really been seen a lot in rootkits so far,
565130	568350	but it's not really an optimal approach for a rootkit.
569130	571330	Viruses need to hide their code.
571610	577890	Rootkits not only need to hide their code, but they also need to hide changes to operating system components.
578870	581890	Polymorphism is not necessarily an optimal solution for that
581890	589250	when you consider that you have the memory-based equivalence of, say, tripwire or other types of integrity checkers.
589870	595470	So, basically, what we wanted to do is we wanted to figure out a way to hide in memory
595470	601150	such that we actually hook the memory of the system without actually changing the code at all.
601730	604730	And that gave rise to ShadowWalker,
604730	610090	which we're coining kind of as a prototype for the fourth generation of rootkit technology.
611570	616930	Basically, the alternative to polymorphism is virtual memory subversion.
618550	622890	Basically, what we're going to be showing you today is a proof-of-concept demonstration
622890	627830	that a rootkit is capable of transparently controlling the view of memory
627830	633030	seen by user applications, kernel drivers, and the operating system itself.
634730	639950	Now, the cool thing about this technology is the fact that there's a minimal performance impact.
640270	642750	Because we exploit some features in the hardware,
643570	650570	that means that basically our memory hook engine hiding a rootkit is virtually undetectable.
650570	653910	It has no slowdown or system performance hit.
653910	658610	Obviously, this makes this type of technology attractive to not only a rootkit,
658610	663210	but also to maybe a virus, or a worm, or spyware applications.
666250	669930	Just a few implications of virtual memory subversion.
670030	676690	For a long time, rootkit scanners relied upon the integrity of the operating system API.
676910	680870	Like Jamie mentioned, ever since the second generation of rootkits,
680870	682870	rootkits have been hooking the API,
683270	688770	and upper-level processes can no longer trust the results returned to them by the API,
688770	694030	either the user-level API or the kernel-level API, depending upon where the rootkit is hooking.
694030	698250	So basically, rootkit scanners have gotten a little bit smarter.
698250	704650	They're starting to realize that they can't rely upon operating system APIs anymore.
704650	708870	But even those rootkit scanners that don't rely upon operating system APIs,
708870	713230	they still rely upon the integrity of the virtual memory system.
713810	718810	So therefore, when a security scanner does a read of a certain memory address,
718810	722250	it expects to see the data that's actually stored at that address.
722250	729250	What we're proposing is actually to return some data that is, in fact, not actually stored at that address.
729530	732950	So basically, there are two implications here.
733010	735670	If we can control a scanner's memory reads,
735670	743730	then we can fool signature scanners and potentially make a known rootkit or virus code immune to an in-memory signature scan.
743730	748470	Because basically, the scanner will access the range of memory where the rootkit code is stored,
748470	756350	and it will be returned data which is a clean copy or does not have the rootkit code.
756570	759310	We can also fool integrity checkers.
759310	765550	Those kind of checkers, like Jamie Butler, presented a talk on a tool called Vice,
765550	768330	which basically attempts to detect hooks.
768330	774270	Hooks typically work by replacing the beginning of the function prolog in an API
774270	780010	with a jump instruction to a stub, which is the rootkit code.
780010	790510	So basically, under normal situations, you would not expect to see the first instruction in an API to be a jump instruction.
790510	796090	The normal code would be such stuff as stack setup code, allocation of local variables.
796390	802430	So basically, Jamie uses heuristics like this to determine if functions are hooked.
802430	810250	Basically, the implications for this is that if we are subverting that particular function in memory,
810250	817710	the scanner would perform a read, and it would receive a clean copy of that API function code,
817710	821690	yet the actual code that it's executing is actually the hook code.
824440	830520	Since we're going to be talking about the subversion of virtual memory, we're going to need to do a little bit of a review.
831100	836540	This is stuff that is normally covered in a college-level operating systems class,
836540	841100	but I know that for most people, we probably need to review some of this stuff.
841460	845600	First thing we're going to talk about is virtual address space layout,
845600	848660	and then we're going to talk about some of the concepts of virtual memory.
848660	854240	We're going to go over the ideas of paging and segmentation, page tables and PTEs,
854240	860140	how virtual-to-physical address translation actually occurs, what the page fault handler does,
860140	863580	and then some performance issues associated with paging,
863580	868420	and how those are actually mitigated using a hardware solution, or the translation look-aside buffer.
868880	876120	Finally, we'll talk about different memory access types, and some little eccentricities with the x86 architecture.
878240	887060	So basically what you have here is a layout of the two most common layouts for the Windows virtual address space.
887060	892060	The first one breaks the virtual address space up into two main components.
892060	896820	Like Jamie said, we have two modes of operation under Windows.
896820	903380	We have a privileged mode, which is basically kernel-in, and we have a non-privileged mode, which is basically user-in.
903380	906880	The memory address space is arranged similarly to that.
907240	911600	The lower two gigabytes correspond to user-in address space.
911600	916520	That's going to contain your application code, DLL code.
916520	920940	The upper two gigabytes is going to be where the operating system kernel is.
921220	928280	In the upper two gigabytes, you're going to have N2S kernel, PAL, hardware abstraction layer, boot drivers.
928280	935880	You're going to have key operating system structures, the process objects that Jamie was talking about,
935880	942640	process page tables, and then non-page pool and cache memory.
943080	951020	Alternatively, we have a second address space layout, which has been used on some of the Server 2003 systems,
951020	955340	which actually allows you to expand the user address space up to three gigabytes.
956460	961560	By far the most common layout is going to be the one where it's split in half.
963680	967640	So, basically, what is the main idea behind virtual memory?
967800	973300	Basically, the idea is we want to separate the virtual from the physical address spaces,
973300	976320	or separate the virtual and physical address spaces.
977420	982580	By that, what I mean is the virtual address space is the size of it.
982580	986880	It's going to be defined by the width of your memory bus.
986880	994120	So, if you have a 32-bit system, that means that you have the ability to address 2 to the 32,
994120	998260	or approximately four gigabytes of continuous memory locations.
998680	1003520	So, therefore, your virtual address space spans from zero up to four gigabytes.
1004000	1009520	In contrast, most of us don't really have four gigabytes of RAM installed on our system unless we're really lucky.
1009760	1016100	So, therefore, we can say that our physical address space is constrained by the amount of RAM on our system.
1016100	1023720	And the amount of RAM is most likely going to be less than the four gigabyte limit for the virtual address space.
1024240	1032460	So, basically, virtual memory concerns managing these virtual and physical address spaces by dividing them into fixed-size blocks.
1032740	1036420	If those blocks are all the same size, we have a paging architecture.
1036420	1040340	If those blocks may be variable sizes, it's a segmentation architecture.
1040920	1045460	The x86 architecture is actually a combination of segmentation and paging.
1045460	1053200	However, for the purposes of our talk, we're focusing upon the paging architecture, because that's the level that we're going to subvert.
1053840	1062260	As far as how this maps, there's actually mapping information that actually maps a virtual block to a physical block.
1062260	1069220	And the OS is what actually maintains this mapping information and determines which virtual blocks map to which physical blocks.
1069860	1074240	Like I said before, the virtual address space may be larger than the physical address space.
1074240	1081500	And also because the OS is managing this mapping, virtually contiguous memory blocks do not need to be physically contiguous.
1083400	1087920	This actually shows an illustration of those two points on the previous slide.
1087920	1091860	As you can see, we have our virtual address space divided up into blocks.
1091880	1095340	Under a paging architecture, we call these blocks pages.
1095700	1099120	The physical address space is smaller than the virtual address space.
1099120	1102180	It's also divided into fixed-size blocks.
1102180	1104120	This is termed frames.
1106060	1113380	Basically, as you can see, the virtually contiguous blocks do not necessarily have to be physically contiguous.
1115560	1121300	So, what actually maintains this mapping information that the OS uses?
1121340	1124490	This mapping information is contained in page tables.
1124880	1131000	And page tables consist of entries called PTEs, or page table entries.
1131000	1135260	Page table entries contain at least two pieces of useful information.
1135680	1140160	They contain status information, and they contain mapping information.
1140320	1148500	The page frame number bits are the bits that actually describe where that page actually maps to in physical memory.
1148820	1151860	There are also a bunch of status bits, as you can see.
1151860	1156120	A few of the most important ones would be the V there for valid.
1156120	1162060	That's going to determine if the page is actually resident in memory, or if it's been paged out to the disk.
1162340	1170940	You have the writable bit, which is going to be concerned with protection, whether or not that page is read-only, or whether it's going to be writable as well.
1171220	1175160	You also have some bits, the cache-disabled, the dirty bit.
1175460	1182320	These are bits that the operating system uses in its virtual memory management for page swapping and such.
1182320	1185780	And then the last bit of interest is going to be the global bit.
1185780	1195260	The global bit is interesting because it determines whether or not this particular mapping information will be flushed from the hardware cache on a context switch.
1195460	1198060	This actually becomes important later on.
1200980	1207040	So, basically, here's an illustration of the big picture, just to kind of summarize all these ideas.
1207040	1214180	We have our virtual address space layout divided into user space and kernel space.
1214180	1219390	We have our pages, which are the divisions of the virtual address space.
1219940	1225580	We have process page tables located in the kernel memory section.
1225580	1231330	Process page tables contain PTEs, which contain status information and mapping information,
1231600	1236680	which will basically say where those pages are located out in physical memory.
1239820	1247580	So, how do you go from an address to actually figuring out where that particular page is in the page table?
1247580	1254760	Basically, virtual addresses can encode the information necessary to index into page tables.
1255060	1258740	Page tables may actually be single-level or multi-level.
1258800	1262500	The x86 maintains a two-level paging architecture.
1263700	1267460	Basically, we divide the virtual address into two pieces.
1267460	1273300	We're going to divide it into the virtual page number, which is going to contain the page table indexing information,
1273300	1281300	and we divide it into the byte index, which is going to contain an offset from the physical frame in physical memory.
1281640	1286360	So, basically, the virtual page number, in this case, since we have a two-level architecture,
1286360	1293480	basically what that means is not only do we have a page table, we also have a page directory.
1293480	1298640	And, basically, the page directory is a table of pointers to page tables.
1298940	1302500	And the page tables, of course, mean pointers to physical frames.
1303060	1308400	This actually is used to... a two-level scheme is used to actually save memory,
1308400	1312360	since the page directory is going to have to be resident.
1312580	1318060	So, basically, in this case, our virtual page number is actually divided into two pieces.
1318060	1323920	We have to be able to figure out the index into the page directory so we can locate the correct page table,
1323920	1329360	and then we have to figure out the index into the page table so we can locate the correct page frame.
1329380	1336960	So, basically, under x86, the upper ten bits in the virtual address are going to provide your index into the page directory,
1336960	1340760	while the middle ten bits are going to provide your index into the page table.
1343620	1348840	This slide gets a little bit complicated, but I'm going to give it a go here to try to explain it.
1348980	1353720	Basically, there's a number of steps involved in virtual-to-physical address translation.
1353760	1355740	This is performed by the hardware.
1356440	1362740	The first step is going to be to locate the page directory, the base address, the page directory and memory.
1362940	1367020	The page directory base is actually located in the k-process block.
1367020	1372120	The physical address is also located in CR3, which is the control register on the processor.
1373380	1377420	So, basically, the first step is to locate the base of the page directory.
1378080	1385480	The second step is going to be to locate the actual entry in the page directory that contains the pointer to the page table that we need.
1386080	1390180	So, basically, we're going to extract the upper ten bits from the virtual address
1390180	1396960	and use that to add to the page directory base to obtain the entry in the page directory table.
1398220	1408160	Now, the contents of this page directory entry is basically the pointer to a page table, or the base physical address of the page table and memory.
1409040	1417480	So, now at this point, we have the base address of the page table, and now we're trying to get to the PTE, or the entry in the page table.
1417480	1420860	So, to get to the page table entry, now we do the same type of thing.
1420860	1427640	We take the middle ten bits of the virtual address and use that to add to the base address of the page table,
1427640	1435060	and we now get the actual page table entry, which is going to contain the pointer to the page frame in physical memory.
1435960	1443180	So, now at this point, we have a pointer to the page frame, and we're actually looking for some byte within that frame.
1443180	1452440	So, it's finally at this point that the actual byte index comes in, and we add that to the base address of the physical frame to actually resolve the full physical address.
1459450	1467950	Like we said earlier, the physical memory may be smaller than the amount of virtually addressable memory you have,
1467950	1474030	so therefore the OS may need to move some pages from main memory out to the disk to satisfy current memory demands.
1474790	1483910	Basically, when the OS does this, it marks the PTE for the page in question as invalid, writes it out to the disk,
1483910	1488410	and the next time that page is accessed, it's going to generate a page fault.
1488770	1494770	A page fault is basically just an interrupt that is going to cause a vector to an interrupt service routine,
1494770	1497270	which in this case is going to be the page fault handler.
1498110	1501510	There are actually several conditions where a page fault can occur.
1501510	1507490	The most common condition is going to be the case where the page table entry is marked invalid,
1507490	1512250	and that page has been swapped out to the disk and needs to be brought in.
1512470	1517770	There's a little caveat to that, because not only does the PTE need to be marked invalid,
1517770	1524050	that entry cannot be present inside the TLB, or the hardware cache of virtual to physical mappings.
1524050	1526630	This becomes very important later on.
1527250	1532150	The second situation where you can have a memory protection violation is going to be,
1533170	1536830	basically, user mode code attempting to access kernel memory,
1536830	1541190	or perhaps an attempt to write to memory that's marked as read-only.
1543530	1548370	For all of you guys that I lost on that previous slide of virtual to physical translation,
1548370	1551590	I have a little bit clearer one that shows the whole page fault path.
1566160	1569520	Okay. First thing, you have a memory access.
1570160	1576000	So the first thing we do is we need to look it up in the page directory to resolve the actual page table.
1576320	1581200	In this case, it's present. So we can move on and go out to the page table.
1581220	1584980	Now, in the page table, we're trying to look up actually where the physical frame is.
1585180	1590140	In this case, that particular PTE has been marked invalid, and a page fault is generated.
1591300	1593900	This causes the page fault handler to be invoked.
1593900	1599740	The page fault handler now is responsible for issuing the disk.io to go out to the page file
1599740	1603560	and load that frame back into main memory.
1603740	1608500	Once it's loaded back into memory, it now marks the PTE as valid.
1612180	1617260	As you can see, some people would say that paging is not such a good idea.
1617440	1621100	This is because there's this de-performance hint associated with paging.
1621100	1628080	Basically, we take one memory reference and we basically turn it into three memory accesses.
1628080	1631000	So we're cutting our performance by a factor of three.
1631360	1635340	Basically, the first thing we have to access is the page directory. That's one memory reference.
1635340	1638520	We have to access the page table. There's another memory reference.
1638620	1642780	Now we have to actually go out and get the byte in the correct physical address.
1642780	1644540	There's our third memory reference.
1644540	1649720	So actually, in the best case, every single memory access requires three memory accesses
1649720	1652720	to resolve the virtual to physical address.
1652940	1659640	In the worst case, not only do we need three memory accesses, now we might potentially need two disk.ios.
1659680	1664600	Because since we have a two-level paging scheme, our page tables may be non-present
1664600	1669960	and our actual page frames may be non-present as well.
1669960	1673220	So therefore, you may have up to two additional disk.ios.
1673220	1678180	So as you can see, paging introduces a speed performance hit.
1678180	1684500	Hardware designers found this to be unacceptable and they developed a solution for this to help mitigate this problem.
1684500	1687620	Their solution was the translation look-aside buffer.
1687840	1694440	The TLV is basically a high-speed hardware cache, generally implemented in associative memory,
1694740	1700000	that holds the most frequently used virtual to physical mappings.
1700000	1707260	So basically, the TLV caches the information held in the PTEs for certain pages that are used frequently.
1708820	1713000	The TLV is actually a lot smaller than main memory,
1713000	1719620	which means that it's possible that an entry in the TLV could actually be evicted
1719620	1726840	if another page that maps to that TLV entry needs to be loaded into the TLV.
1726840	1731140	So basically, the TLV is actually first on the memory access path.
1731140	1733500	It sits in front of the page table path.
1734220	1738020	So therefore, on the memory access, the TLV is actually searched first,
1738020	1740700	before we ever even go out to the page tables.
1741260	1746720	Since it is high-speed associative memory, that means that a reference found in the TLV
1746720	1754960	can be resolved much, much faster than it can be resolved by even going out and doing a single memory reference in main memory.
1754960	1759400	If that reference is actually found in the TLV, we say it was picked.
1759420	1762380	If it was not found, we say that we had a miss.
1762940	1767040	The x86 actually uses a split TLV architecture.
1767200	1770100	And what I mean by that is there's actually two TLVs.
1770100	1774320	There's one that holds translations for code, that's the iTLV,
1774320	1778480	and there's another one that holds translations for data, that's the dTLV.
1779000	1782500	I should note that modern TLVs have extremely high hit rates,
1782500	1786760	which means that most translations are actually resolved via the TLV cache,
1786760	1790380	as opposed to actually having to go out to the page tables,
1790380	1793160	which significantly increases performance.
1794820	1800380	This is just a simple example of a TLV search.
1800860	1804580	Basically, the TLV is a cache. It consists of two parts.
1804580	1808720	You have a tag, which in this case is going to be the virtual page number,
1808720	1812480	and then you have the corresponding frame that maps to that virtual page number
1812480	1816620	in the data section of the cache line.
1816700	1819720	Basically, when a memory reference occurs,
1820420	1823480	the TLV tags are going to be searched in parallel
1823480	1826960	to see if they can find a match on that virtual page number.
1827020	1831820	If they can, the data, or the corresponding physical frame mapping,
1831820	1833300	is going to be returned.
1833300	1838560	In this case, we had a TLV hit on virtual page 17,
1838560	1840840	and its corresponding frame is 84.
1843040	1850920	So, basically, here I have an illustration of the memory access path that includes a TLV.
1851820	1857500	We're also going to stick with the x86 architecture, which actually has a split TLV.
1857500	1864100	So that means that on a memory access, code accesses are going to be checked in the iTLV.
1864900	1868960	So, in this case, we have a hit on the iTLV.
1868960	1872340	We now have the corresponding frame, which is 132,
1872340	1875320	and we can go directly out to physical memory.
1875600	1878600	In this case, as you can see, since we had a TLV hit,
1878600	1881880	we were able to completely bypass the page tables.
1884180	1887220	It may be possible that we don't have a TLV hit.
1887220	1888540	We could get a miss.
1888660	1892920	And what's even worse than a miss, now that we have to go out to the page tables,
1892920	1897140	now we might actually get a page fault, which will kill performance even further.
1897420	1900640	So, in this case, our memory access is a code access.
1901000	1905940	It goes out to the iTLV, searches it, it's not there, so now we have a miss.
1906520	1908960	So, now we have to go out to the page tables.
1909240	1914380	In this case, we go out to the page tables, and we find something we need is not present.
1914720	1916540	So, we have a page fault.
1916540	1919980	Now the OS page fault handler has to be invoked.
1920000	1923540	It has to go out to the disk, bring that frame into memory,
1923540	1931900	and finally mark that PTE as being present before the access can be completely resolved.
1934420	1938580	So, basically, we have three memory access types.
1938580	1940040	Everyone's familiar with these.
1940040	1942520	We have read, write, and execute.
1942520	1950080	Unfortunately, a little caveat to the x86 architecture is we actually only have two memory access types.
1950080	1953980	We actually have read-execute and read-write-execute.
1953980	1958380	By that, I mean the execute access is implied to all memory.
1959160	1961500	This poses a slight problem.
1961500	1967380	In some cases, we might like to actually differentiate between execute access and read-write access.
1968220	1975580	One common place where this might be the case would be the implementation of non-executable memory.
1975580	1980000	This is used as a buffer overflow protection scheme.
1980280	1985060	Basically, you have your stack space, which is typically readable and writable.
1985060	1986920	I mean, you store data on the stack.
1986920	1992980	But normally, the stack does not contain executing code unless a buffer overflow attack is in progress.
1992980	2000160	So, therefore, heuristically, if we were able to detect an execute access over a read-write access on the stack,
2000160	2007320	we could say if we detect an execute, that heuristically, there's a good probability that we're in progress with buffer overflow attack.
2007960	2016300	Now, the little caveat here is, like we said, x86 doesn't let us distinguish between read-write and execute.
2016560	2021400	So, basically, we have not had hardware support up to this point.
2021400	2023040	We do now have some hardware support.
2023040	2026600	But previously, there was a project called PAX.
2026600	2034600	Basically, PAX implemented read-write-no-execute or non-executable memory semantics using strictly software support.
2034600	2038760	This was before there was any hardware support for non-executable memory.
2039120	2046040	Windows XP Service Pack 2 and Server 2003 Service Pack 1 now also implement software support
2046040	2051000	in the form of what Microsoft calls Data Execution Prevention or DEP.
2051460	2060220	As a side note, hardware support has been added for non-executable memory onto 64-bit processors as well as the Pentium 4.
2063300	2075520	Well, in the case of a rootkit, it's also kind of advantageous to be able to distinguish between executable and read-write access to a range of memory.
2075520	2084120	Basically, we're going to take an offensive stance on the PAX technology, which, it's been around for a while.
2084120	2085980	This technique's been around for a while.
2085980	2092180	But so far, it hasn't really been shown how you could invert that technique for malicious purposes.
2092560	2095480	So, basically, we want to hide code.
2095500	2098620	So, we want to differentiate between read-write-and-execute.
2098620	2110880	So, the idea is, if we have a read access of the code section of our rootkit driver, for example, that's going to be a very strong heuristic that a scanner's trying to locate us.
2111480	2116680	So, basically, what we would want to do in that case is we want our rootkit code to run.
2116680	2131320	But if a scanner tries to read it, we want to basically return an image of that memory that does not contain the rootkit code, or contains something clean, in the case of a modification to the operating system.
2131480	2137840	So, basically, what we're proposing here is we're going to do an implementation that is the inverse of PAX.
2137840	2144480	That is, it's an implementation of execute, allowed, but diverted read-write memory semantics.
2147220	2154620	We're going to use the PAX technique that PAX discovered to implement non-executable memory.
2154620	2157100	But, in this case, we're going to use it to hide a rootkit.
2157280	2163880	So, like I said, the technique is not totally new, but the application is somewhat new.
2164280	2167380	So, basically, there's three implementation issues here.
2167700	2171280	First, we need a way to filter, execute, and read-write accesses.
2171280	2172360	Step one.
2172360	2176980	Second, we need a way to fake the read-write accesses once we detect them.
2177240	2182020	Obviously, we don't want the scanner to receive the correct data when it reads our rootkit memory.
2182280	2186280	Lastly, we need to ensure that performance is not adversely affected.
2186780	2196300	Obviously, this would not be a viable solution if, when we install our rootkit, the system administrator notices that his machine is suddenly running really, really slow.
2198420	2207480	So, to solve the first problem, basically, we said earlier that if we mark the PTE as invalid,
2207480	2213020	the next memory access that occurs to that page is going to generate a page fault.
2213260	2220600	So, basically, that means that we can trap memory accesses by marking their page table entries as invalid,
2220600	2225820	and basically hooking the page fault handler and replacing the operating system's page fault handler.
2226460	2231880	In the actual page fault handler, we have access to some interesting information.
2232140	2234460	We have the saved instruction pointer.
2234460	2238700	We also have the virtual address where the fault occurred.
2238860	2245820	So, therefore, if our instruction pointer equals the address of where the fault occurred, we can say that this was an execute access.
2245860	2248820	Otherwise, it's going to be a read-write access.
2249440	2259900	There's one important thing to note here, and that is the fact that our memory hook for the rootkit has to work safely with the operating system's memory management,
2259900	2263260	because the operating system's resolving page faults all the time.
2263260	2269760	So, that means, in practical terms, that if we're going to mark pages not present to capture memory accesses,
2269760	2277660	then we also must be able to distinguish whether those memory accesses are a result of someone trying to access the hidden page,
2277660	2281220	or a result of normal operating system paging activity.
2281380	2285660	In order to satisfy that, we actually impose two constraints.
2285920	2290880	The first constraint could be that pages that are hidden are required to be a non-paged memory.
2290880	2295060	That means there's no possibility that the OS could page that file out to the disk.
2295640	2302160	The second constraint could be, if you're using pageable memory, that you use an operating system API to lock it down.
2304620	2314520	So, once you're able to detect execute from read-write, well, now comes the issue of, well, how are we actually going to fake the read-write accesses?
2314660	2322720	So, basically, this is the technique that was shown in PAX, that it used to implement the inverse of what we're going to talk about,
2322720	2328660	and that is, we're going to desynchronize the hardware caches, the TLBs.
2328660	2334540	Like I said, the x86 has two of them. It has one for code, which is searched on execute.
2334540	2337280	It has one for data, which is searched on read-write.
2337500	2349000	So, therefore, a memory access, under normal situation, the ITLB is going to contain virtual page number and corresponding physical frame,
2349000	2351500	and the DTLB is going to contain the same thing.
2351500	2356220	So, in this case, for virtual page number 12, we see it maps to frame 2.
2356220	2359440	For the DTLB, it also maps to frame 2.
2359440	2365440	Under normal situations, read-write and execute, they all map to the same physical frame.
2367400	2370300	However, what if we could desynchronize them?
2370300	2377820	What if we could have the ITLB to actually map off to a different physical frame than the DTLB?
2377820	2385960	So, basically, the idea here is that the ITLB contains a pointer to a frame which contains the rootkit code,
2386360	2393060	and the DTLB contains a pointer to the frame which either has a clean copy of something or some random garbage,
2393060	2395200	which is not the rootkit code.
2396160	2401600	So, basically, since all these translations are performed at the hardware level,
2401600	2408960	this is going to be transparent to the application program, to the kernel driver, or even to the operating system.
2409460	2416860	So, basically, once we've decided that we're going to desynchronize the TLBs, the question is, well, how do you actually do this?
2418240	2421060	TLBs are almost entirely hardware controlled.
2421400	2428420	However, there is a little bit of support for software control, which, in this case, happens to be enough support to implement this.
2428420	2432400	First of all, we have the capability to flush the TLB.
2432860	2437780	Basically, we can flush the entire TLB by reloading register CR3.
2437780	2440680	This normally occurs on a context switch.
2440700	2447780	On a context switch, typically, CR3 will be reloaded, which ends up flushing the entire TLB,
2447780	2451140	except for global entries, which will remain in the TLB.
2451140	2458940	This is mainly a performance enhancement for operating system components, which will remain resident at all times.
2459780	2466920	Also, we also have a method of not only flushing the entire TLB, but of flushing an individual entry in the TLB.
2466940	2469840	That would be the invalidate page instruction.
2470800	2475400	So, now that we've established that we can flush the TLB, how about loading it?
2476300	2486640	It is possible, actually, to load the TLBs separately, which means that actually executing a data access loads the DTLB, but not the ITLB.
2487040	2492520	Conversely, executing a call loads the ITLB, but not the DTLB.
2492520	2498740	So, therefore, it is possible to discretely load the two TLBs separately and desynchronize them.
2500760	2506420	So, basically, our proof-of-concept implementation consists of two main components.
2506420	2513480	We have the memory hook engine, which has a hook installation component, which sets up the hook,
2513480	2524100	and then a custom page fault handler, which basically is responsible for filtering execute read-write accesses and correctly manually loading up the right TLB.
2524100	2529320	Also, our second component is going to be a modified FU rootkit.
2529340	2536700	So, basically, we've modified Jamie's rootkit to work in collusion with our ShadowWalker.
2539220	2544880	So, basically, on memory hook installation, there are several steps that have to be performed.
2544960	2550560	First of all, since we're going to mark pages not present, we need to install a new page fault handler.
2551180	2558800	Once we've done that, on a page fault, we're going to need to be able to determine, relatively quickly,
2558800	2569120	if that fault is due to one of our hidden pages being accessed, or if it's due to the actual operating system performing normal paging activity.
2569120	2575320	So, in order to do that, we just insert that page into a simple hash table, so we can perform a quick lookup.
2575900	2578460	Next, we mark the page not present.
2579580	2586600	And then the last step is really the most important here, because we said that the TLB is first on the memory access path,
2586600	2592360	which means that a page fault is generated, one, when the PTD is marked present, but like I said earlier,
2592360	2595140	two, when that entry is not present in the TLB.
2595140	2599480	So, therefore, we perform an explicit flush of that page that we're hiding.
2599500	2604820	This means that on the next memory access, we will be able to generate a page fault.
2605420	2608840	If you could please hold your questions to end, we'll have time for questions.
2612910	2621150	So, basically, the custom page fault handler's main responsibility is to filter, read, write, and execute accesses for hooked pages.
2621630	2626830	If it determines that the page is not a hooked page, meaning it's just a normal operating system page fault,
2626830	2629390	it passes it down to the OS handler.
2630070	2637830	If it is a page fault due to a hidden page, it's either going to manually load the ITLB or manually load the DTLB,
2637830	2639850	depending upon the type of access.
2640630	2644390	Most memory references will be resolved via the TLB path.
2644390	2647610	So, intuitively, you would think that you would be generating a lot of page faults,
2647610	2649750	it would take a big hit in performance.
2649750	2653890	Not the case, because we're using the hardware caching mechanism.
2653890	2656170	We're just simply synchronizing it.
2656650	2662070	So, basically, we will still have page faults, but page faults are not as many as you would think,
2662070	2666230	since the TLB path will handle most of the memory references.
2666770	2672250	Page faults on the hooked pages will, of course, occur on the first execute or data access to the page.
2672250	2676590	Remember, we had to flush it, flush the TLB, when we instantiated the hook.
2676830	2679970	It will occur on the TLB cache line eviction.
2679970	2686990	So, it's possible that the mapping for that hooked page got evicted from the TLB.
2686990	2691470	Well, the next time that a memory access occurs, it will now generate a page fault,
2691470	2695210	which the page fault handler will now reload the correct mapping into the TLB,
2695210	2697090	and that memory access will go through.
2698370	2703710	Likewise, the last case would be on an explicit TLB flush context switch,
2703710	2706750	if the global bit has not been enabled.
2709090	2715430	So, basically, here we have some really rudimentary page fault handler pseudocode for what's going on.
2715990	2720570	So, basically, we are only hiding kernel pages right now.
2720570	2723930	So, we're going to disregard user land accesses.
2723930	2727050	So, in the page fault handler, we want this to be as efficient as possible,
2727050	2730310	so we don't want to tie things up if we're not interested in handling this fault.
2730330	2733990	So, the first thing we do is we just check if the processor mode is in user mode.
2733990	2737110	If it is, we pass it down. We're not dealing with user mode.
2737270	2743490	If the faulting address is a user page, we're also going to pass it down, because we don't hook user pages.
2743990	2750470	In contrast, if the fault is from a hidden page, now we're going to check if it's a read-write or an execute.
2751010	2755570	If it's an execute, we're going to jump over to load the ITLB.
2755690	2759950	If it's a data access, we're going to jump over to the load DTLB code.
2760610	2768030	Basically, in the load ITLB, what we're going to do is we're going to basically replace that physical frame information in the PTE
2768030	2775630	with the mapping for the actual physical frame that contains the rootkit code, because we want it to execute.
2775890	2781950	We're going to temporarily mark that PTE as present to allow the memory access to go through.
2782030	2786530	We're going to perform a call into the page, which is going to load up the ITLB.
2786530	2792670	I should note here, I forgot to put this on the previous page, that we do have to perform a call.
2792790	2800850	Basically, that means that we need to find an empty byte in our given page that we can insert a return-off code to.
2801310	2806530	In practice, if you're going to type sections, say in a driver, those are PE sections,
2807110	2812810	so therefore there's going to be some alignment, so therefore there's normally some empty space in there.
2812810	2816850	So you shouldn't really have trouble finding one byte that you can just patch a return into.
2817390	2823930	So therefore, basically we just make a call to this point in the page where the return has been patched,
2823930	2830590	and it returns control back to the pagefault handler, and in process, loads up the ITLB.
2830890	2837310	Finally, the PTE is marked as non-present again, so we can catch subsequent accesses.
2837310	2843110	We also replace the frame back with the original innocent-looking frame,
2843110	2848890	and we go ahead and we return back to the faulting application, or driver as the case may be,
2848890	2853550	without passing down to the OS. The OS doesn't need to have any knowledge of this default.
2854170	2858610	If it's a DTLB load, basically the steps are a little bit simpler,
2858610	2863930	because by default, we're going to maintain the clean mapping in the PTE.
2863930	2870690	So therefore, we just mark it present, perform a read access, and then mark it non-present again.
2870950	2874210	And then, of course, return without passing down to the OS.
2876830	2882970	So, basically all this information so far concerns how you would hide executable code.
2888800	2893460	Okay, we're running out of time, so I'm going to go ahead and skip this section on data hiding.
2893460	2898260	This slide should be available probably on rootkit.com within the next week or so.
2900320	2904120	So basically, I'm going to move ahead and we're just going to talk a little bit about the rootkit here.
2904560	2910640	The rootkit is, of course, the object that we are implementing this process on to actually hide it.
2910780	2915080	It's proof of concept. It doesn't really do anything malicious. It just hides processes.
2915700	2921520	It runs as a system thread. It has no dependence upon user land initialization,
2921520	2925500	which means it has no symbolic link or no functional device in the driver.
2925920	2930620	And also, basically, we envision this rootkit as being an in-memory rootkit,
2930620	2934720	meaning that ideally it would be installed via a kernel-level exploit.
2934940	2940140	Obviously, if this rootkit driver is sitting on the disk, we open up a whole new can of worms for detection
2940140	2944060	and basically invalidate all these faulty things that we're trying to do.
2944140	2946880	So basically, we never want it to reside on the disk.
2946880	2953580	This is a perfectly reasonable thing if we consider attacking, say, a server system, which is infrequently rebooted.
2953580	2959820	Chances are high that this rootkit will sit in memory, and by the time we come back, it'll still be there.
2962280	2968660	So, lastly, the impact on system performance. Like we said, modern TLBs have high hit rates.
2968800	2974020	That means most translations will be resolved via the TLB and not the page fault path,
2974020	2979020	which means that we're going to have very little performance hit.
2979040	2988820	I can't speak from a performance metric point of view here, because we haven't really done any rigorous testing on performance,
2988820	2997940	but I can say that, subjectively speaking, hiding Jamie's rootkit with this ShadowWalker memory hook engine,
2997940	3001960	there is no subjective, noticeable performance impact.
3002560	3007940	Clearly, the performance impact will probably vary depending upon the number of pages you're having to hide.
3008060	3012760	In this case, hiding a kernel driver, how many pages do you really have?
3012760	3019600	You have four or five sections in a PE, portable executable, so chances are you only have four or five pages.
3019600	3023600	If they're page-aligned, four or five pages is really negligible.
3024220	3029180	So, for small numbers of pages, we haven't observed any performance impact at all.
3031200	3037120	As this is not really a weaponized attack tool, there are a number of known limitations.
3037660	3041240	Jamie and I have done this basically on our spare time.
3041320	3047320	So, basically, we've not implemented a fully productized or weaponized version.
3047480	3050260	So, first of all, there's no PAE support.
3050260	3055620	PAE basically extends addressability from 32 to 36 bits.
3055620	3057340	We don't support that yet.
3057340	3060600	There's no hyper-threading or multi-processor support.
3060600	3067680	There's clear issues with regards to synchronization problems involved with porting this up to a multi-processor system.
3067680	3069500	We've not addressed those yet.
3069600	3073840	Currently, we only hide 4K-sized kernel pages.
3074000	3077680	We are theoretically capable of hiding 4MB pages.
3077680	3082320	The x86 architecture actually has two page sizes, 4K and 4MB.
3082320	3089660	The main point of interest with the 4MB pages are going to be hiding of NTOS kernel, which is sitting on a 4MB page.
3089660	3096020	Obviously, an interest to a rootkit developer who wants to install hooks into the operating system kernel.
3096080	3098340	Currently, we can't hide NTOS kernel.
3098340	3102400	There's some technical difficulties with that, which we're working to resolve.
3102580	3110160	But it's quite effective for hiding drivers and other drivers, such as maybe Indus, which sit in the 4K page range.
3110160	3113900	So we could hide the hooks in the network drivers, for example.
3115800	3118980	As far as detection, I'm going to go over this real, real brief.
3118980	3121140	I think we're really running out of time here.
3121480	3129020	First of all, like we said earlier, we have to make the constraint that we have non-paged memory,
3129020	3135460	that we're marking non-present, so we can differentiate our page faults from OS page faults.
3135460	3140320	Obviously, non-present pages in non-paged memory are heuristically abnormal.
3140340	3144800	If that's sufficient to indicate that a rootkit's installed, highly debatable.
3144800	3146400	But it's still abnormal.
3147000	3151260	Obviously, the page fault handler code itself cannot be marked not present,
3151260	3156080	because that would imply that we're marking the page containing the page fault handler as not present.
3156080	3160040	We would end up with lots of recursive problems of recursive re-entry.
3160040	3165520	Therefore, the solution for hiding the page fault handler, we have to fall back to more tried-and-true approaches.
3165760	3169540	It's small, it's written in assembly, there's no APIs,
3169540	3173800	so polymorphism seems like a fairly reasonable solution to that problem.
3174380	3177560	Likewise, it's also difficult to conceal hooks on the IDT.
3177560	3181580	Currently, this proof of concept makes no effort to conceal the IDT hooks.
3181660	3185340	Yes, this rootkit is very easily detected right now because of this,
3185340	3189600	but that was not really our goal. We're just showing a proof of concept.
3191000	3197420	Right now, we're really running short, so I'm going to proceed to the demo and skip the last couple slides.
3207090	3212090	I know we're late, so if anyone has any other engagements, feel free to head on out,
3212090	3216870	but I am going to go ahead and perform the demo for anyone that's interested.
3219330	3221650	I'm going to do a GUI version of this demo.
3221650	3227470	I have a hardcore Softice version if anyone wants to see after the talk.
3231660	3234380	Basically, the first thing I'm going to do is...
3234380	3238760	Right now, I'm using Driver Monitor. It's a tool with the Softice driver suite.
3238760	3241000	It allows you to load a kernel driver.
3241640	3246160	The first thing I'm going to do is I'm going to go ahead and load up Jamie's rootkit.
3254150	3256590	Our driver has started successfully.
3256590	3259830	Now, if we enter Softice...
3263490	3267950	we can get the base address of where this driver is loaded in memory.
3283470	3287430	This is the virtual address of where this driver is loaded in memory.
3287430	3290810	We're going to go ahead and dump it. Dump the memory at that address.
3291350	3296370	For all of you guys that use hex dumps all the time, this should look pretty familiar.
3296370	3302030	This 4D5A, that's simply the MZ signature inside the PE header.
3302390	3307450	Right now, what we're seeing is the PE header of this rootkit driver loaded in memory.
3308430	3315350	At this point, I'm going to go ahead and load up the memory hook engine, ShadowWalker.
3328400	3330860	It started up successfully.
3332300	3335600	Now, we're going to go ahead and perform another memory dump.
3337780	3340180	Now, it's gone.
3347740	3352800	So, we'll take questions offline. We're leaving the room. We're being evicted.
3352960	3356840	We have swag books. We'd love to hear from you. Thanks a lot.
