Monday, September 30, 2019

DOC to PDF with MS Word and Vbscript


Dear readers,

Before we get into the subject -
It has been some time now that I gave an update to my blog. One of the demotivating reasons for not updating the blog is the fact that much of the content like the assembly language code and related tutorial are all very old and were hosted in geocities. I just dumped the archive here. And I wanted to re-organize this blog a little. However, some of my blog entries are newer but just that some older technologies are used.

There are two reasons to this (1) It simplifies the learning 2) Old is still Gold. Hence today, I am going to present a simple scripting task using a tool of a "bygone era" called VBScript. The words "tool of a bygone era" is not mine. I had a discussion the other day with a colleague of mine and we were discussing on how many new technologies are available now especially programmer tools. How much value add do they bring especially when we need to port some of our old code to the new technology and so on. I have spent quite some time with VB, VBA , VBScript in the past. I was always thrilled with the "automation power" VB family had. I could make the system talk with just a line of code in VBScript. I could animate the "OLD MS ASSISTANT" MS Agent in a few lines of code, animate it and make it show some text. Those were old and golden days. Now we have newer technologies and newer ways of doing things. Yet thanks to Microsoft, they don't just dump these technologies. They do consider the "cost" involved for any business to move to a newer technology. They also consider a developer's pain when it involves learning up a new paradigm. Of course there are some low level technologies that have changed over time and it has indeed presented problems to the developers. But as most of you know, right now it is just crazy, how many technologies we have and how many technologies businesses are using (mixed programming).

Anyway let us get into business. So the task is - you have a lot of .doc files, in a directory, that you want to convert to .pdf. There are tools available now as part of some professional editions of "PDF readers" and probably there are some scripts available. Frankly I didn't do much research. I just want to remember VB hence I just got into the coding. Now there are at least two ways, that I could quickly think of, to do this task. One is to load the files and then "Print them to PDF". The second option is to use the MS WORD's inbuilt "Export to PDF" function. So below is the code that I came up with using the latter option.

If not for this script, you would normally open each .doc file and export it to PDF. Again some "PDF creators" would have in-built option and integration with MS Word etc., I haven't done much research on this.

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

Set objFSO = CreateObject("Scripting.FileSystemObject")
currentpath = objFSO.GetParentFolderName(WScript.ScriptFullName)

Set wordapp = CreateObject("Word.Application")
wordapp.Visible = False

objStartFolder = "."

Set objFolder = objFSO.GetFolder(objStartFolder)

Set colFiles = objFolder.Files

For Each objFile in colFiles

if instr(1,objFile.Name,".doc",1) > 0 then
iname = currentpath  & "\" & objFile.Name
oname = currentpath  & "\" & objFile.Name & ".pdf"

WScript.Echo "Converting " & objFile.Name & "..."
wordapp.Documents.Open iname
wordapp.ActiveDocument.ExportAsFixedFormat oname,&H11

        wordapp.ActiveDocument.Close
end if
Next

wordapp.Quit
Set wordapp = Nothing
Set objFSO = Nothing

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

Just save above script as doc2pdf.vbs or use any name you want to but save to the directory where you have the .doc files. Open a command prompt. Ensure you are in that directory and run the script as "cscript doc2pdf.vbs". 

How this works - First we use the automation power of vbscript to instantiate two objects, one that deals with the "filesystem operations" and the other to deal with "MS Word". Indeed you need to have MS Word installed in the system for this to work. 

We create a "Word application" first. We use the "File system object" to write some script that will do the "dir effect" or listing all files in a given folder. Note that I am using "." to make the script use the current directory. I leave it to the reader to modify the script to take any path and convert files in that path. Also I haven't dealt with a lot other use cases. For example you may want to convert .docx not the old format .doc or you just want to skip .docm and so on. Again these tasks are left to the readers. 

So here, we just traverse the directory, list all the files, check if the name has ".doc" and if yes then we use the Word application's instance and invoke the "export" option. To do this we use the instance of Word and open each document one by one. We then call the method ExportAsFixedFormat and pass it the name of the output file. Here I just append a .pdf to the actual .doc file name, so if your doc name is Sreejith.doc it gets exported to Sreejith.doc.pdf. And I also pass as the second argument, the value &H11, which is nothing but decimal 17. This is important and this means, I need a PDF file as output. Once a document is done, we close it and then we loop all over again, loading a new document and this continues for as long as the script "finds a .doc file".

That's it for today :)

Long live VB (hopefully VB.Net holds the fort)!

Happy scripting!

Saturday, October 13, 2018

Windows assembly tips


Hello all,

I am "briefly back" to the blog... Before we start, if you like (or do not like) my blog/articles or you have comments on it, please drop me an email at gnomicbits@gmail.com.

I was yearning to update this blog for sometime now, with some new learning. Much of the new musings are around system/software security. But then I thought to hold it off for some more time so that I can provide you better content.

Meanwhile, I was getting back to my "routine coding on assembly". I always miss assembly. I try my best to see where I can "plug-in" some assembly coding whether it be at work or it be training/seminars or  sometimes I even try to introduce it during small talks.

Recently I was writing some simple utilities at work. These are designed to be support tools for some earlier work. So there is "nothing official" about the development. It simply caters to troubleshooting the existing software stack. Thus it was a good excuse for me to write it in assembly language.

So what I plan this time for this article, is to have this as a "rolling article" (assuming you already know assembly) where I keep updating this article with new ideas or tips. So keep checking this page, whenever you can because "writing assembly" is like morning constitutionals for me. You may see new tips. I am looking forward to learn from you readers too . If you feel, I could improve somewhere or I have gone wrong somewhere, please drop me an email with the details. I will definitely revert.

Well.. I think this preface is enough for you to get some context on why/how I am back. Let us get started....

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

TIP#1:- One of the most sought-after code in GUI-programming, especially when we create our own utilities is - how to center the window and make it the top most window. And most of us would have copied and saved this code from the MVP blogs several years back or may have rehearsed more than once, the algorithm we use, to do this. So some of this may be repetitive work for some of you... While I am sure there are code snippets out there, in the internet , I will try to make this more useful by annotating the code so you can read the code and its explanation "at the same time"...


;;;;; { The procedure we call to center the window and make it the "top-most"};;;;;;

;;;;; { Takes one argument that is the window handle} ;;;;;;;;;;

SetMainWinSizeAndPosition proc uses edi  hwnd:HWND


;;;;;;;;; Declare the locals ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LOCAL hdc:HDC
LOCAL screenwd:DWORD
LOCAL screenht:DWORD
LOCAL winwd:DWORD
LOCAL winht:DWORD
LOCAL winx:DWORD
LOCAL winy:DWORD
LOCAL sizemult:DWORD
LOCAL sizediv:DWORD

;;;;;; Strategy :-

;;;;;;;  (1) Sizing the window :- While you can pass any values for the width and height, here I use
;;;;;;;  the screen resolution and make the window width and height as 1/3rd of the "screen sizes"
;;;;;;;
;;;;;;;  (2) Positioning it in the center of the screen :- Imagine the cartesian plane and your window ;;;;;;;  on it. Assume that we
;;;;;;;  have a finite width and height for this plane since we superimpose your screen with the
;;;;;;;  cartesian plane on top of it; If we half the screen width we get the "x-coord" and
;;;;;;;  if we half the screen height
;;;;;;;  we get the "y-coord".  If we simply made these values the x & y then the top left corner of our
;;;;;;;  window will be in center not the window itself! So we need to also half the width and height of
;;;;;;;  our window and subtract that from the previously calculated x & y.
;;;;;;;  Technically we shouldn't assume that the x and y coordinates are at the center of the screen
;;;;;;;  when we try to superimpose the imaginary cartesian plane. The coordinates and the "layout"
;;;;;;;  depends upon the "mapping mode". I won't digress to that topic here.
;;;;;;;
;;;;;;;
;;;;;;;  (3) Making it top most :- Simply pass a flag to a Windows API!

;;;;;;;  Windows APIs - GetDC(), ReleaseDC(), GetDeviceCaps() and SetWindowPos().

;;;;;;;  Have the multiplier and divider set.. it is 1/3rd and we can simply set this value to anything
;;;;;;;  else later

 mov sizemult,1
 mov sizediv,3

;;;;;;;; We need to first get the device context of the window. From this we can get the device
;;;;;;;; capabilities which will include the horizontal and vertical screen resolutions
;;;;;;;;

 invoke GetDC,hwnd
 mov hdc,eax
 invoke GetDeviceCaps,hdc,HORZRES
 mov screenwd,eax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  screen width
 invoke GetDeviceCaps,hdc,VERTRES
 mov screenht,eax ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; screen height


 ;;;Sizing the window
        ;;; Multiply by "multiplier" and divide by the "divider".

 mov eax,screenwd
 mul sizemult
 div sizediv
 mov winwd,eax  ;;;;;;;;; save the window's width


 mov eax,screenht
 mul sizemult
 div sizediv
 mov winht,eax    ;;;;;;;;;;;; save the window's height


 ;;;Centering the window

        ;;;;;;;;;;;;;; Use an optimization (shr) this time instead of  div
        ;;;;;;;;;;;;;;;

 mov eax,screenwd
 mov winx,eax
 shr winx,1       
 mov eax,winwd
 shr eax,1
 sub winx,eax


 mov eax,screenht
 mov winy,eax
 shr winy,1
 mov eax,winht
 shr eax,1
 sub winy,eax


 ;;; Now set size and position of the window and make it
 ;;; the "top most" window

 push 0
 push winht
 push winwd
 push winy
 push winx
 push HWND_TOPMOST
 push hwnd
 call SetWindowPos

 push hdc
 push hwnd
 call ReleaseDC

 Ret
SetMainWinSizeAndPosition endp


$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$


TIP#2:- Now for an interesting GUI hack. You see a few applications with "grayed off buttons" on their dialog boxes and windows, probably as an attempt to tell you that you are using a trial version of their software. The app might require you to register to ensure the buttons are enabled etc. How to enable these disabled/grayed off buttons etc.?

This is a very simple and ugly hack for "standard controls" like buttons. This means you can't use this trick for "custom controls". The typical "button" you see when you get error message pop ups from shell/explorer etc is an example of a standard control - class Button. And this works on windows related to the current thread's desktop. Thus if you are looking at enabling these "disabled buttons" you can use below program and that is the entire program (add the headers/sections etc).

start:
invoke MessageBox,0,addr Message,addr AppName,0

;Enumerate all top level windows, and on each enum, enumerate
;all child windows and pass WM_ENABLE message

invoke EnumWindows,OFFSET EnumWindowsProc,0
invoke ExitProcess,0

EnumWindowsProc proc hwnd:HWND,lparam:LPARAM
push 0
push OFFSET EnumChildProc
push hwnd
call EnumChildWindows

mov eax,TRUE
Ret
EnumWindowsProc endp


EnumChildProc proc hwnd:HWND,lparam:LPARAM
push 1
push hwnd
call EnableWindow

mov eax,TRUE
Ret
EnumChildProc endp

end start

There are other complex code written by authors for the same purpose using hooks. They may serve a more complex scenario. But to simply enable these buttons etc, the above code is enough. If you still want an executable to see it in action you can download EnableAll.zip from below location.
https://sites.google.com/site/gnomicbits/downloads

Note:- I had chrome open while testing this and the pages simply froze.Use judiciously!

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$


TIP#3:- How to check if the current thread has "admin" rights?

What I assume here is that the reader is looking for a way to determine if her/his code has certain "admin rights" For example: for creating a folder in say "Program files" directory or so. We also can determine if we are running on an "elevated mode" under "UAC". Starting Windows Vista, most programs we execute go through a "UAC" layer that intentionally runs the program with "least privilege security". This means the program (probably a malware) won't do evil things easily. UAC would try to gain the "user attention" by throwing pop-ups asking for "elevation" or sometimes it silently stops executing the program and so on. Thus as a developer you may want to check if the code is running in an "elevated mode". I have annotated the code to some extent. I will try to provide detailed theory on Windows security in a future article.

I use the same example provided in msdn here
MSDN ref: https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-checktokenmembership

IsRunningAsAdmin proc

LOCAL AdministratorsGroup:SID
LOCAL xyz:ptr SID

lea ebx,AdministratorsGroup
mov xyz,ebx

;;; First get SID for local administrators group
lea edx,xyz
push edx
push 0
push 0
push 0
push 0
push 0
push 0 
push DOMAIN_ALIAS_RID_ADMINS         
push SECURITY_BUILTIN_DOMAIN_RID  ;;;security boundary via RID
push 2 ;;;;sub authorities count 
lea edx,NtAuthority ;;;;top level authority. "5"
push edx
call AllocateAndInitializeSid

.if (eax)

;;; Now check if our token has the above SID in its membership list. A thread has an associated
;;; token that it gains from its parent process or through impersonation. In this example (msdn)
;;; we assume we are using our own token (thread)

lea edx,bAdmin
push edx
push xyz
push NULL
call CheckTokenMembership

.if !eax
MsgBox addr err
.endif

.if bAdmin
MsgBox addr isadmin
.else
MsgBox addr isnotadmin
.endif
.endif

push xyz
call FreeSid

Ret
IsRunningAsAdmin endp

We also have defined below variables in the data and bss sections

NtAuthority SID_IDENTIFIER_AUTHORITY <SECURITY_NT_AUTHORITY>
bAdmin BOOL ?

Below is a demo of the above code executed in a normal and an elevated command prompt displayed side-by-side



$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$


TIP#4:- Ok now something that most of you would love, especially assembly enthusiasts who are still learning up assembly or struggling to cross the Beginner-Intermediate zone (like me)!
How to use Kip Irvine's resources with MASM SDK? :)

While he has given fantastic hacks with VS projects and you could just start with community edition you may still feel that that IDE is no better than Winasm. Yet you would still (if you are like me) love to use Qeditor to write your programs. Irvine's book including the libraries and macros are really good for beginners as well as pr0f3ss10n4l c0d3rs ;) ;).  So to rephrase the problem, how to integrate the resources so that you can use masm sdk with Irvine32 lib. Follow steps below

1) Copy all the .inc files to MASM include
2) Copy all the .lib files except for user32 and kernel32 because we already have them. I never
got time to look into why they are larger than the SDK's.
3) Include only Irvine<##>.inc in the code which in turn includes SmallWin.inc etc.
4) Ensure to include libraries as needed like kernel32...
5) Ensure to include Irvine<##>.lib too.
6) When you are using Qeditor do "Console assemble and link" not the regular one because
he has written console based sample programs mostly.

That's it and it worked for me for quite a few samples.

Meanwhile I am just trying Hutch's new x64 kit in tandem with Vasily Sotnikov's version of MASM sdk. That way you get all the incs and libs as needed :) Yeah I am too lazy! :)


$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$




Saturday, February 25, 2017

Security coding in Windows Kernel (Anti-malware) - 1



Hi folks,

Firstly I would like to thank all the viewers of my blog. I have 964 hits so far. I got 7 feedback via email so far (all productive). Thanks especially to Sysinternals forum, Stack overflow and Linkedin. I will try to incorporate most of the things requested in the feedback. So keep sending your comments to gnomicbits@gmail.com or comment to the posts.



Today's post is more on windows security. It is especially useful for programmers who write anti-malware applications (beginners) or who want to understand the internals of some of them. I found it really difficult to find an appropriate title but finally gathered few words.

While I could have written the code in 'C' or 'C++' I wanted to thank Hutchison and Four-F and I didn't find a better way to do that. The "innovation" around reduction of "development-kit" size is quite appreciable. Secondly Four-F kit is simply incredible. It also includes undoc headers. Together MASM (and assembly language know-how) and Four-F's KMD kit is a must for any security professional especially System Hacking (coding). It also would be the first steps to going for other versions of "ASM" that provide 64-bit support.

Although I haven't studied differences between "undocumented API" available in the Four-F kit and Alex's NDK, completely, I still think it would be a value-add to convert the NDK to ".INC". Something I am working on... I know these are almost history but isn't that also important for Malware Analysts :) - they will agree.

So today I wanted to talk about three very important and elegant SPI (SPI = System programming interface. SPI < > API), that windows has been providing since Windows 2000. I will put focus on Windows 2000 (like most other posts of this blog) but it is still applicable to later versions and I will try to add enough information about changes in newer OS version.

So the 3 functions that I would prefer to call as "SPI" but are categorized under "Driver support routines - process support) are...

PsSetCreateProcessNotifyRoutine - Monitors new process creation.
PsSetCreateThreadNotifyRoutine - Monitors new thread creation.
PsSetLoadImageNotifyRoutine - Monitors mapping of executable images (before execution) to virtual memory.

Here is my ASM code (skeleton process monitor)...

.386
.model flat,stdcall
option casemap:none

include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc
include \masm32\include\w2k\ntoskrnl.inc

includelib \masm32\lib\w2k\ntoskrnl.lib

NotifyMe proto :HANDLE,:HANDLE,:BYTE

.data
pcreate db "Process is created",0
pexit db "Process is exiting",0
snotify db "Success: Notification routine registered successfully!",0
fnotify db "Error: Unable to register notification routine!",0
format db "%s:%d",0

.CODE

DriverEntry PROC pdrvobj:PDRIVER_OBJECT,pRegPath:PUNICODE_STRING

push 0
push offset NotifyMe
call PsSetCreateProcessNotifyRoutine

.IF eax == STATUS_SUCCESS
push offset snotify
call DbgPrint
.ELSE
push offset fnotify
call DbgPrint
.ENDIF

 mov eax,STATUS_SUCCESS
ret
DriverEntry ENDP

NotifyMe proc ParentId:DWORD,ProcessId:DWORD,Create:BYTE
 
cmp Create,FALSE
jz lexit
push ProcessId
push offset pcreate
push offset format
call DbgPrint
jmp getout
lexit:
push ProcessId
push offset pexit
push offset format
call DbgPrint
getout:
ret
NotifyMe endp

END DriverEntry

Use the above code with MSDN documentation and it should be fine.  Here is the gist anyway - Just register a notification routine and you will be notified every time a process is created at least with 1 thread (at least one thread will be there in most cases). There are new routines in later OS that wasn't there in Windows 2000. For example, in W2K it was required that the driver remains loaded until system is shutdown. Now we have options to Un-register the notify routines in case of thread and image load notifications. We are able to block the process creation too (documented functions) in later versions. With the protection of critical kernel data structures in later windows versions, such routines and facilities are important because earlier (say W2K times) we had to do other tricks to get the same task done. There are some "C" sample codes available online and especially in Malware related books. I didn't find an ASM sample (may be I didn't look enough). Anyway I wrote a few samples on above SPI. So it is quite simple.  Below is the output, for the above sample process notification code, using Debug viewer utility.


That's it for today! :)

Sunday, May 15, 2016

Windows Internals [Process II - Code]


Before I begin, please comment on the posts, so I know what is wrong and what is right with the posts. Please consider that I am not charging you for this information and your comments will be a motivation.

If you haven't read the part I of this, I would recommend you to do so now. And if you have then let us go directly to the code.

//****************************************************************************/
NTSTATUS DriverEntry(IN PDRIVER_OBJECT _pdrvobj,IN PUNICODE_STRING _CM_Entry)
{
        char *eproc;
        long cpid;
       
        _pdrvobj->DriverUnload=Kext_Unload;

         eproc = (char*)PsGetCurrentProcess();
         cpid = *((long*)(eproc + 156));
    
         while(1)
         {
                DbgPrint("%d : %s", *((long*)(eproc + 156)),eproc + 508);
                eproc =    (char*)(((char*)(((LIST_ENTRY*)(eproc + 160))->Flink)) - 160);
                if( cpid == *((long*)(eproc + 156)) )break;
         }
        
   
    return STATUS_SUCCESS;
}
//******************************************************************************/

A small piece of code isn't it? :)   So what are we seeing here. First we use a documented function that is accessible to driver writers easily to get a pointer to the structure EPROCESS (PsGetCurrentProcess()). Remember that I am using the Windows 2000 driver kit to compile and every bit of compatibility that I am explaining and assuring is tested. At this point I am keeping it bare metal so I am only going to use pointers and simple data types to manipulate the kernel info in the algorithm not high-level structures.  So if you add 156 bytes from the start of EPROCESS you get the process ID which is declared long. long takes 4 bytes. So now that we dereference that memory location, we can get the PID of a process. Since this is driver entry called in arbitrary context , I assume mostly it will show the current process as "System". You can see that in the part I of this article. It is system that is the first process in the list. Next is the grand loop. Inside this, I use the existing pointer to EPROCESS and go to offset 508 to get the process name. Ok what is the next line that is a mess? Couple of things are done here. So, after the PID the next information that is stored in EPROCESS is LIST_ENTRY. As driver writers would know this is used for managing a doubly linked list and driver writers often use this. It is a self-referential structure with a forward and a backward link. What do they store? As you can imagine they store pointer to the next LIST_ENTRY. And the next important question is not, what the next ENTRY points to but where it is contained. It is contained in the next EPROCESS structure or structure that is created to inform about the next process. So if we jump 160 bytes from start of EPROCESS use the value contained in that address, go to that address and subtract 160 from it, we get starting address of next EPROCESS. I have done a lot of casting to char*. We need to cast the so extracted LIST_ENTRY address before subtracting 160. Otherwise it will subtract LIST_ENTRY sized value from that (pointer arithmetic). A lot of that code can be simplified if we introduce, the EPROCESS structure itself and cast some of these addresses to be of type EPROCESS.

Therefore you can re-write that to the below having declared structures necessarily...

//****************************************************************************/
typedef struct EPROC
{
        char blah[156]; //At this point we are not worried about what is in these 156 bytes
        long pid;
        LIST_ENTRY *Flink,*Blink;
}__EPROCESS,*__PEPROCESS;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT _pdrvobj,IN PUNICODE_STRING _CM_Entry)
{

         __PEPROCESS eproc;
        long pid;
           
        eproc = (__PEPROCESS)PsGetCurrentProcess();
        cpid = eproc->pid;

        while(1)
        {
              DbgPrint("%d:%s",eproc->pid,(char*)eproc + 508);

              eproc = (__PEPROCESS) ((char*)eproc->Flink - 160);
               
              if(eproc->pid == cpid) break;
        }                                  
}
//****************************************************************************/

But would we ever stop with that? For starters, you could manipulate these pointers and change their values causing certain havoc. This is what root kits do like hiding the process. Similar structures exist for everything else managed by the kernel - security related structures, networking related, file system related.. imagine what power we have now, having understood how to manipulate the low level structures? There are so many websites and blogs that talk about these. One is a blog that I follow myself. Joanna's Invisible things. She is definitely one of my most favorite Gray Hats. :)

Of course you cannot easily do that now, since Windows has kernel patch guard etc. And if you didn't know already, similar techniques are used in the other operating systems and no system is immune to these attacks. For there is always a way if there is the will... So what do you have in your mind?

Windows Internals [Process I - Theory]


Before I begin, please comment on the posts, so I know what is wrong and what is right with the posts. Please consider that I am not charging you for this information and your comments will be a motivation.

In this post I will show you a bit about windows process internals. I am writing this with few assumptions - you know "C" programming, you know about windows driver programming basics and that you also have the book Inside Windows 2000 (3rd ed) by David Solomon and Mark Russinovich (or equivalent). Well yes, do not be surprised that I am discussing about windows 2000 here when we already have a windows 10 in the market. Some great minds have said - "Keep it simple, but not simpler". So let us keep the problem simple and I will also ensure it isn't made quite simpler that the problem definition itself is confined with wrong constraints. But any windows internals book would do. If you want to test this code you will also need Windows 2000 (itself) or modify some values that I will tell you later. You will need the driver kit of course. An understanding of Windows API and C is a plus.

Most of you would only need to just know that like any other operating system, windows also uses several structures to maintain processes. As I understand from the great minds who wrote the internals book (my role models in fact) , windows do not contain "Tasks" unlike *NIX.

However the basic strategy is more of less same for the algorithms used in these operating systems. In a nutshell (thinking as a developer), you need a structure that holds all information about a process. This can be a very complex structure indeed. It can have a lot of nested structures within but as we know, let us keep it simple. So this will contain information about say the name of the process, the ID assigned to the process (internally called client id). It will contain few more details like when the process started or how much time elapsed since the process started, information about the threads that it contains etc. As you see the moment we talk about a significant entity like "thread" you realize that a thread itself would contain some information related to it. This might be in another structure. Therefore you will have some nested structure within this structure for process. And now when you take the internals book that I said above and go to the page where the authors listed the structure of process, you may get bewildered :) There is a lot of information stored in the structure and in that book it is printed on 3 - 4 pages. Imagine how much the Kernel developers of Windows would have thought about it. As the great Niklaus Wirth put it Program = DataStructure + Algorithm.

I always like to see what is it that we are dealing with, so the above image shows the output of our effort. It shows information that DbgPrint() in a driver code gives. Of course you would recognize these are process names with their IDs.

Ok a little bit theory on the basics. So Processes in windows is basically managed primarily with two important structures. EPROCESS and KPROCESS. A kernel debugger (along with symbols) can show you the information. Now that these things are documented online you can always look at that. Finally you can always check the internals book for the information. KPROCESS keeps a lot of very low level aspects of a process like scheduling where as Executive structure (EPROCESS) keeps a high-level view of process information. Even much of the operating system deals with and relies on the EPROCESS for their programming chores. Usually programmers (system) won't need to access these structures directly. Even driver writers won't need to worry about them. But that is internals right?  So EPROCESS contains some information and for the rest it "contains" KPROCESS within.

Security professionals would know about this because these structures were exploited in the past to hide process and keep other activities stealth (rootkit). One of the areas I am trying to specialize in is rootkits. Today we don't get to see them because of the strict "code integrity" that operating systems like Windows have introduced (since Vista actually) and every version there is something new. Digital Signature, patch guard etc. Perhaps in another post I can show you some of those hackish code. It is indeed very interesting. You may also want to know (as I said in Native api related post), these structures were used by some software to protect their code. Antivirus for example used to use these structures, over write some data with pointers that work like a "detour", "trampoline" and so on.

So what is the task we have in hand and what are we going to learn from it? We will try to access this EPROCESS structure in the kernel (not user mode so you need to write a driver), we will use it to enumerate the process as shown above. We thereby learn how process information is handled internally (to some extent).


Thursday, March 31, 2016

Introduction to Native (aka Undocumented) API


Hi all,

My second post to my new blog and I am even more excited than I was when I posted the first one. That is because this week I was looking at some really "hackish" stuff. Anyway, if you are here then perhaps you already have heard of the so called "undocumented api" or "native api". If you are checking this post as part of my updates sent to forums and sites like linkedin then perhaps you may not know have heard of this so called undocumented API or native API.  So take a deep breath... this is going to be a long read...

This post is for beginners who are developers, who have used C, C++ and Windows API already and who wants to dive into the "hackish" dimensions of Windows. Windows gives a mammoth API for programmers who develop with C/C++/Assembly language. Windows also uses this API. However Windows OS also have some "hidden" interfaces that it uses apart from the Windows (public) API. I assume you are aware of this documented API aka Windows API.

So today it is a misnomer when we it as  "undocumented API". Most of these native APIs are documented now.. Starting Windows NT days till today, there were some belligerent and talented hackers who did surgery on Windows OS and studied the internal facilities (code) that the operating system uses and also exposes to public especially programmers. Native API had a very advanced documentation in sysinternals website earlier, when it wasn't part of Microsoft and the articles were "visible". There are so many books and MSDN articles written on it. I have referred exploit-monday.com and rohitab.com for some code. I used exploit-monday to refer the AMAZING documentation of some "undocumented" data structures and functions put by Matt Graeber. I only referred rohitab's forum to check if my code is "really fine".

http://www.exploit-monday.com/2013/06/undocumented-ntquerysysteminformation.html

http://www.rohitab.com/discuss/topic/40504-using-ntquerysysteminformation-to-get-process-list/ 

The code I have put here is definitely different from rohitab's because I use explicit linking. But before I talk about all that... firstly what is this so called "native" or "undocumented" API? Well if you think about all the available application programming interface that Windows provides as layers, then one layer (almost the top) comprises of Windows API that is offered but a huge set of DLL files like KernelBase(kernel32), User32, Gdi32, advapi32, crypt32 etc... Now if that is the first layer or the interface you use as a programmer, then the next layer is "NTDLL" layer (let us put it this way to simplify). To get a clear understanding I would ask the reader to refer to the popular Windows Internals books..  They are called "undocumented" because Microsoft never documented these functions calls and data structures officially (until now where there is some partial documentation). NTDLL.DLL is like a layer by itself and most of the API calls from the other DLLs call functions of NTDLL.DLL. This is one of the major "code path" and by code path I mean flow of code from user mode to kernel mode. NTDLL is like the last layer of user mode and then the code switches mode to kernel mode and your code (actually in form of system calls and requests to system) continue executing. The user mode Windows API is quite well documented. The kernel mode programming interface is provided by ntoskrnl, hal etc and that is documented too. Driver developers will be and should be well aware of those interfaces. Native API sits somewhere in between but isn't well documented. Microsoft uses this layer to do proprietary advancement to "chewing" user mode code and then pushing "massaged" code to kernel mode for execution. You can imagine this is an abstraction offered to the Windows API itself. You call Windows API. Windows API calls NTDLL functions (native api) and then there is mode switch to kernel and so on..
Did that simplify it better than any other documentation about native API? I don't know... if you think so please comment on this article. I can edit and make it better if needed.

Okay, so why do you need to know about "native api"? -  You can easily achieve almost all tasks with Windows API. Even higher frameworks offered to programmers like .Net, Java etc all use Windows API. Even the OS uses some of the functions offered by this "Windows API" layer. You would still use native api to know more about what happens inside. You use it because it can give more information and all that perhaps in a single function call. You use it because you skip a layer (WinAPI) and so your code saves several CPU cycles as you skip a lot of instructions that make the Windows API. Hackers and Anti-hackers have been using the undocumented interfaces for a long time. Hooks and Undocumented APIs are favorite for both hackers and anti-hackers. If you are lucky you will find an article about how Symantec anti-virus got into trouble because of using undocumented interfaces (not necessarily native API) after the introduction of Windows Vista. Microsoft warns users from using these APIs because they can change. For most tasks programmers SHOULD use Windows API.

Ok enough of theory, let us put it to practical use... what I will show in this article is a famous code that people usually look for.. "How to list processes using native api" or "NtQuerySystemInformation"?

"NtQuerySystemInformation" is a very powerful function that resides in ntdll.dll. As the name says, it queries a lot of system information. You choose the "information" that you want from an "enumeration". Matt has  re-documented (seems to be the latest) in exploit-monday.com. It was indeed documented well, in year 2000 by Gary Nebbet. As said earlier, Microsoft can anytime make any changes to these structures, enumerations and functions. I haven't really done a diff but I could see a few more "information type" added to this enumeration in Matt's.

I assume the reader knows to use LoadLibrary() and do explicit linking.  I won't explain all those elementary stuff here. So here is what we need to do, to enumerate the processes currently managed by the operating system... (experts see how careful I was when I said that (lol) - processes don't run + there can be terminated-but-hanging-around processes (zombies) - refer Mark/David/Alex discussion in their internals-book as well as some forums).

You may use winternl.h to get the limited Microsoft documentation (and access) of native api/structs. I prefer to have my own list and I used Matt's documentation said earlier. winternl.h has been used and ntdll library has been implicitly linked, in the code that is shown in rohitab, that is if you want to do it that way... We will do explicit linking here...pretty much what people are mostly looking for...

//main.cpp
#include "undoc.h" //uses exploit.monday.com - NtQuerySystemInformation.h

#define BLOB_SIZE 1024 * 1024 //Allocate a really large pool

int _tmain(int argc,PTSTR *argv)
{
    SYSTEM_PROCESS_INFORMATION *pspi_next,*pspi;
    NTSTATUS ns;
   
    pspi = (PSYSTEM_PROCESS_INFORMATION)HeapAlloc(GetProcessHeap(),0,BLOB_SIZE);

    NtQuerySystemInformation(SystemProcessInformation,pspi,BLOB_SIZE,NULL);

    pspi_next = pspi;
   
    do{ //Well, if this code is even running then there are at least 8 - 10 process in the system
        //depending upon the OS version (even WinPE!)

        _tprintf(_T("ID:%6d\t"),pspi_next->UniqueProcessId);
        wprintf(L"%s\n",pspi_next->ImageName.Buffer);
      
        pspi_next = (PSYSTEM_PROCESS_INFORMATION)(((PBYTE)pspi_next) + pspi_next->NextEntryOffset);
    }while(pspi_next->NextEntryOffset);

    HeapFree(GetProcessHeap(),0,pspi);

    return 0;
}

//undoc.h header [excerpted - rest you can refer exploit-monday and also give credit to the
//author Matt for his valuable contribution]

typedef NTSTATUS (NTAPI *_NtQuerySystemInformation)
    (IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    OUT PVOID SystemInformation,
    IN ULONG SystemInformationLength,
    OUT PULONG ReturnLength OPTIONAL
    );


_NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)
        GetProcAddress(LoadLibrary(L"ntdll.dll"),"NtQuerySystemInformation");


Explanation:-

We are using the undocumented NtQuerySystemInformation function to get some process information stored in the memory that is managed by the operating system. This information is SYSTEM_PROCESS_INFORMATION structure and we have one per process. We do not know how many processes... So allocate a large blob. Thankfully Heap functions do support this amount I gave. If not use VirtualAlloc (rohitab.com).  Given one chunk of this information, it has an offset to the next chunk of the same "information set". Use that "link" to traverse all "chunks" until you reach end of blob. We don't check if it is end of blob, instead we see if "NextEntryOffset" goes 0. The rest is basics..

FEEDBACK/COMMENTS VALUABLE AND WELCOME!

Thursday, March 10, 2016

How to verify a PE digital signature (Extended version)



A very good morning/afternoon/evening.. I am writing this at 3:32 AM... so I may say Good Early Morning as well...  I can stay deprived of sleep but not knowledge... :)

Well, if you are checking this topic I assume you already know about digital signatures and especially how they are used on PE (Portable Executable) images. Anyway, I got a project where I had to work on scanning some cabinet files that contain digital signature. And as of this writing, the world (matrix) is going through a significant change. SHA1 is getting deprecated and SHA2 is being implemented all over the world (corporate world).

So the best tool as of now is "signtool" that is provided with the driver development kit, SDK or with Visual studio. There are numerous sites published in the past couple of months and being published now on what is digital signature, how to have multiple signature and what not. So I was reading them and I learned a lot. Anyway I primarily started with two sources that I want the reader to read before he reads further...

https://msdn.microsoft.com/en-us/library/windows/desktop/aa382384%28v=vs.85%29.aspx

http://forum.sysinternals.com/topic19247.html

Most of the information you see there are already documented. What is not documented is some stuff on how to check signature via catalog files and the sysinternals link provides code for exactly that problem. But not adequate so I added up two calls to make it better

http://forum.sysinternals.com/discuss-howto-verify-digital-signature-of-a-file_topic19404_page2.html

(Look for Karthik - emm so many pseudonyms!!!)

But there are some good things that has happened. Microsoft has documented a few more functions that I am sure will be fully used for coding in the coming months and there will be so many websites perhaps MSDN itself showing up some codes that use them. I didn't see anyone using them as of this writing and of course I am using it for my project. I tried writing to a well known forum and they rejected my article for aesthetics, so here comes my first page! Ok, enough of stories and history...

So Microsoft has documented some functions that are in WinTrust.dll. Some sort of WT helper functions. I assume WinTrust helper functions.  "Signtool" (wdk 8) do not make use of these calls apparently. Only one of these functions was found. Anyway so what we can do now that we weren't able to do a year back or so is to check signature via WinVerifyTrust (venerable) and also use some information that it "stores" to get additional information.

All the functions including data structures used by them are documented. So let me just give the code here... (Again I assume you already know well about basic Crypto API usage and also I assume you went through the above forums)...

BOOL VerifyEmbeddedSignature2(HANDLE _h_verify_state)
{
    CRYPT_PROVIDER_DATA *pCPD;
    CRYPT_PROVIDER_SGNR *pCPS;
    CMSG_SIGNER_INFO *pcmsgsi;

     _WTHelperProvDataFromStateData WTHelperProvDataFromStateData;
    WTHelperProvDataFromStateData = (_WTHelperProvDataFromStateData)
                    GetProcAddress(LoadLibrary(L"wintrust.dll"),"WTHelperProvDataFromStateData");

    if(WTHelperProvDataFromStateData == NULL)
          return  FALSE;
      
    pCPD = WTHelperProvDataFromStateData(_h_verify_state);

    if(pCPD == NULL)
            return FALSE;

    _WTHelperGetProvSignerFromChain WTHelperGetProvSignerFromChain;
    WTHelperGetProvSignerFromChain = (_WTHelperGetProvSignerFromChain)                         GetProcAddress(LoadLibrary(L"wintrust.dll"),"WTHelperGetProvSignerFromChain");

    if(WTHelperGetProvSignerFromChain == NULL)
            return FALSE;
       
    pCPS = WTHelperGetProvSignerFromChain(pCPD,0,FALSE,0);
    if(pCPD == NULL)
            return FALSE;
     
    pcmsgsi = pCPS->psSigner;
    printf("Hash Algorithm identifier (OID) - %s : Description - %s",pcmsgsi->HashAlgorithm.pszObjId,
                                    GetAlgorithmName(pcmsgsi->HashAlgorithm.pszObjId));

}

Ok so the only parameter I pass to this function is "state data" that is actually got by calling WinVerifyTrust. How to do that is clearly shown in the MSDN code sample as well as the other sample in SysInternals forum.

Well, the only "extension" that I am providing here is get the hash algorithm. This code returns "SHA 2" OID or "SHA 1" OID. If any file is dual signed the signature at index 0 is pulled. I tested in two cases, one with a dual sign (SHA 1 + 256) and the other with just SHA 256. The GetAlgorithmName is a helper function I wrote to get a friendly name for the OID.

I am sure there is much more we can do now like connect the certificates information we get using these APIs and use "CERT functions" to get complete chaining info!!! 

A BIG THANKS TO MICROSOFT FOR DOCUMENTING THESE APIs!!!