Thursday, November 20, 2014

Use After Free: gflags.exe

Pageheap must be enabled on Internet Explorer (iexplore.exe) to observe crash. To enable pageheap on iexplore.exe, run any of the following commands. gflags.exe is installed as part of VC++, .NET etc when Microsoft Debugging Tools option is selected. executing gflags.exe will help us to easily find memory corruptions and tracing heap allocations/frees. 

gflags.exe /i iexplore.exe +hpa +ust 
Enable the Pageheap (HPA) and User Stack Trace (UST) flags.

gflags.exe /p /enable iexplore.exe /full 

C:\Users\praveend>gflags.exe /?
usage: GFLAGS [-r []] |
              [-r +spp TAG | -r +spp SIZE | -r -spp |
              [-k []] |
              [-k +spp TAG | -k +spp SIZE | -k -spp] |
              [-ro [-d | { -i | -t [;...] } [-
p] ] |
              [-ko [-d | { -i | -t [;...] } [-
p] ] |
              [-i []] |
              [-i -tracedb ] |
              [-p ] (use `-p ?' for help)  |

where: is a 32 bit hex number (0x12345678) that specifies
       one or more global flags to set.
       -r operates on system registry settings.
       -r +spp TAG - Set Special Pool tag value.
                     TAG can have up to four characters.
       -r +spp SIZE - Set Special Pool block size value.
                      SIZE must be in hex format, starting with characters 0x.
       -r -spp      - Disable Special Pool tag or block size.
       -k operates on kernel settings of the running system.
          -k +spp TAG   - Set Special Pool tag value at run time.
                          TAG can have up to four characters.
          -k +spp SIZE  - Set Special Pool block size value at run time.
                          SIZE must be in hex format, starting with characters 0
x.
          -k -spp       - Disable Special Pool tag or block size at run time.
       -ro operates on object reference tracing at boot time.
       -ko operates on object reference tracing at run time.
          -d disables object reference tracing. Do not specify any
             other tracing options.
          -i specifies the image name for which
             to capture traces. All processes started up with this
             image file will be traced.
          -t [;...] specifies the pool tags for which
             to capture traces. Pool tags should be 4 letters each,
             separated by ';'. This value is case sensitive.
          -p maintains traces after the objects are destroyed(permanent).
             By default traces are temporary.
          Unless you are using -d you must specify at least one of the
          -i or the -p options. You may specify both in which case
          objects with a pool tag that is among the list of pool tags
          you specify, created by processes with the image filename
          you specify will be traced. -ko settings override -ro settings.
          Also, if you specify a new set of -ko settings the previous
          -ko settings, if any, are lost (same for -ro).
       -i operates on settings for a specific image file.
           [ignored when not suported in the current OS versions]

       If only the switch is specified, then current settings
       are displayed, not modified.  If flags specified for -i
       option are FFFFFFFF, then registry entry for that image
       is deleted

The `-tracedb' option is used to set the size of the stack trace
database used to store runtime stack traces. The actual database
will be created if the `+ust' flag is set in a previous command.
`-tracedb 0' will revert to the default size for the database.

If no arguments are specified to GFLAGS then it displays
a dialog box that allows the user to modify the global
flag settings.

Flags may either be a single hex number that specifies all
32-bits of the GlobalFlags value, or it can be one or more
arguments, each beginning with a + or -, where the + means
to set the corresponding bit(s) in the GlobalFlags and a -
means to clear the corresponding bit(s).  After the + or -
may be either a hex number or a three letter abbreviation
for a GlobalFlag.  Valid abbreviations are:

    soe - Stop On Exception
    sls - Show Loader Snaps
    dic - Debug Initial Command
    shg - Stop on Hung GUI
    htc - Enable heap tail checking
    hfc - Enable heap free checking
    hpc - Enable heap parameter checking
    hvc - Enable heap validation on call
    vrf - Enable application verifier
    ptg - Enable pool tagging
    htg - Enable heap tagging
    ust - Create user mode stack trace database
    kst - Create kernel mode stack trace database
    otl - Maintain a list of objects for each type
    htd - Enable heap tagging by DLL
    dse - Disable stack extensions
    d32 - Enable debugging of Win32 Subsystem
    ksl - Enable loading of kernel debugger symbols
    dps - Disable paging of kernel stacks
    scb - Enable system critical breaks
    dhc - Disable Heap Coalesce on Free
    ece - Enable close exception
    eel - Enable exception logging
    eot - Enable object handle type tagging
    hpa - Enable page heap
    dwl - Debug WINLOGON
    ddp - Disable kernel mode DbgPrint output
    cse - Early critical section event creation
    sue - Stop on Unhandled Exception
    bhd - Enable bad handles detection
    dpd - Disable protected DLL verification
    lpg - Load image using large pages if possible

All images with ust enabled can be accessed in the
USTEnabled key under 'Image File Options'.
C:\Users\praveend>

Now we can observer crashes in Internet Explore, make Windbg or Olly as your Just In time Debugger!

Wednesday, October 22, 2014

Windows System Programming: File Handling


Creating File

#include <windows.h>
int main()
{
    HANDLE fH = NULL;
    LPCTSTR fileName = "testfile.txt";
    char buff_in[512] = "Creating test file using windows API's";
    int bytes_written = 0;
    int status;
 
    /* http://bit.ly/ISRjD6 */
    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.*/
             SECURITY_SQOS_PRESENT|FILE_ATTRIBUTE_HIDDEN, 
                         /* 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.*/
                         SECURITY_SQOS_PRESENT|FILE_ATTRIBUTE_HIDDEN,
                         /* dwFlagsAndAttributes */
                         NULL        /* hTemplateFile */);
        if (fH == INVALID_HANDLE_VALUE) {
            if (ERROR_FILE_EXISTS == GetLastError())
                printf("file exists(%d)\n", GetLastError());
            else
                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");
        printf("*****************************************\n");  
       
        if(!FindNextFile(hFind, &fileData)) {
            FindClose(hFind);
            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
Run/RunOnce/RunService
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServices HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce 
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
Explorer
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
RegCreateKeyEx
RegDeleteKeyEx
RegQueryValueA
RegQueryValueExA
RegCloseKeyA
RegOpenKeyEx


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


Predefined Keys
    HKEY_CLASSES_ROOT
    HKEY_CURRENT_CONFIG
    HKEY_CURRENT_USER
    HKEY_LOCAL_MACHINE
    HKEY_USERS 


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.
#include<windows.h>
#include<string.h>
#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");
    /*
     * http://msdn.microsoft.com/en-us/library/windows/
     * 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);
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724836%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724880%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724875%28v=vs.85%29.aspx
http://gladiator-antivirus.com/forum/index.php?showtopic=24610

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.

Issue
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.