Beispiel #1
0
int ListDataStreams(char *szFilename)
{
    int iRetCode = EXIT_SUCCESS;

    HANDLE *hFile = NULL;
    LPVOID lpContext = NULL;
    byte pbyBuffer[4096];
    WIN32_STREAM_ID *psStreamInfo = (WIN32_STREAM_ID *)pbyBuffer;
    int uiHeaderLength = 20;
    DWORD dwRead, dwDummy;

    WHANDLEOK(hFile = CreateFile(szFilename, GENERIC_READ, 0, NULL,
        OPEN_EXISTING, 0, NULL));

    while (1)
    {
        WNONZERO(BackupRead(hFile, pbyBuffer, uiHeaderLength, &dwRead,
            FALSE, TRUE, &lpContext));

        if (dwRead == 0) break;

        if (psStreamInfo->dwStreamNameSize > 0)
        {
            WNONZERO(BackupRead(hFile, pbyBuffer + uiHeaderLength,
                psStreamInfo->dwStreamNameSize, &dwRead, FALSE, TRUE,
                &lpContext));

            if (dwRead != psStreamInfo->dwStreamNameSize) break;
        }

        DumpStreamInfo(szFilename, psStreamInfo);

        if (psStreamInfo->Size.QuadPart > 0)
        {
            BackupSeek(hFile, psStreamInfo->Size.LowPart,
                psStreamInfo->Size.HighPart, &dwDummy, &dwDummy, &lpContext);
        }
    }

cleanup:
    // release context
    BackupRead(hFile, pbyBuffer, 0, &dwRead, TRUE, FALSE, &lpContext);
    CloseHandle(hFile);
    return iRetCode;
}
Beispiel #2
0
int next_stream(WIN32_STREAM_ID *dest, struct nt_sid *sid)
{
 DWORD lo, hi, b;

 if(sid->is_write)
  return(-1);
 if(sid->rem.LowPart!=0||sid->rem.HighPart!=0)
 {
  if(!BackupSeek(sid->hf, sid->rem.LowPart, sid->rem.HighPart, &lo, &hi, &sid->lpcontext))
   return(-1);
  if(lo!=sid->rem.LowPart||hi!=sid->rem.HighPart)
   return(-1);
  sid->rem.LowPart=sid->rem.HighPart=0;
 }
 if(!BackupRead(sid->hf, (unsigned char *)dest, W32_SID_HEADER_SIZE, &b, FALSE, TRUE, &sid->lpcontext))
  return(-1);
 if(b!=W32_SID_HEADER_SIZE)
  return(-1);
 sid->rem=dest->Size;
 return(0);
}
Beispiel #3
0
/* Check if file has NTFS ADS */
int os_check_ads(const char *full_path)
{
    HANDLE file_h;
    WIN32_STREAM_ID sid;
    void *context = NULL;
    char stream_name[MAX_PATH + 1];
    char final_name[MAX_PATH + 1];
    DWORD dwRead, shs, dw1, dw2;

    /* Open file */
    file_h = CreateFile(full_path,
                        GENERIC_READ,
                        FILE_SHARE_READ,
                        NULL,
                        OPEN_EXISTING,
                        FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS,
                        NULL);

    if (file_h == INVALID_HANDLE_VALUE) {
        return 0;
    }

    /* Zero memory */
    ZeroMemory(&sid, sizeof(WIN32_STREAM_ID));

    /* Get stream header size -- should be 20 bytes */
    shs = (LPBYTE)&sid.cStreamName - (LPBYTE)&sid + sid.dwStreamNameSize;

    while (1) {
        if (BackupRead(file_h, (LPBYTE) &sid, shs, &dwRead,
                       FALSE, FALSE, &context) == 0) {
            break;
        }
        if (dwRead == 0) {
            break;
        }

        stream_name[0] = '\0';
        stream_name[MAX_PATH] = '\0';
        if (BackupRead(file_h, (LPBYTE)stream_name,
                       sid.dwStreamNameSize,
                       &dwRead, FALSE, FALSE, &context)) {
            if (dwRead != 0) {
                DWORD i = 0;
                int max_path_size = 0;
                char *tmp_pt;
                char op_msg[OS_SIZE_1024 + 1];

                snprintf(final_name, MAX_PATH, "%s", full_path);
                max_path_size = strlen(final_name);

                /* Copy from wide char to char */
                while ((i < dwRead) && (max_path_size < MAX_PATH)) {
                    if (stream_name[i] != 0) {
                        final_name[max_path_size] = stream_name[i];
                        max_path_size++;
                        final_name[max_path_size] = '\0';
                    }
                    i++;
                }

                tmp_pt = strrchr(final_name, ':');
                if (tmp_pt) {
                    *tmp_pt = '\0';
                }

                snprintf(op_msg, OS_SIZE_1024, "NTFS Alternate data stream "
                         "found: '%s'. Possible hidden"
                         " content.",
                         final_name);
                notify_rk(ALERT_ROOTKIT_FOUND, op_msg);
            }
        }

        /* Get next */
        if (!BackupSeek(file_h, sid.Size.LowPart, sid.Size.HighPart,
                        &dw1, &dw2, &context)) {
            break;
        }
    }

    CloseHandle(file_h);
    return (0);
}
Beispiel #4
0
int backup1(struct fout *ff, const char *f)
{
	WIN32_STREAM_ID sid;
	LPVOID lpContext;
	HANDLE h;
	DWORD rv;
	int r, n;

	lpContext = NULL;
	set_backup_privs(1);
	h = CreateFileA(f,
		FILE_READ_DATA | STANDARD_RIGHTS_READ | ACCESS_SYSTEM_SECURITY,
		FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN
		| FILE_FLAG_OPEN_REPARSE_POINT,
		NULL);
	if (h == INVALID_HANDLE_VALUE) {
		r = GetLastError();
		if (r == ERROR_FILE_NOT_FOUND) {
			set_backup_privs(0);
			fout_abort(ff);
			return 1;
		}
		set_backup_privs(0);
		/* try to read it raw */
		if (!backup1_ntfs(ff, f)) {
			return 0;
		}
		/* hooray! it read in- get the security info */
		if (s_flag) return backupsec2(f);
		return 1;
	}

	if (!backupsec(h, f)) {
		r = GetLastError();
		CloseHandle(h);
		set_backup_privs(0);
		SetLastError(r);
		return 0;
	}

NEXT_STREAM:
	rv = 0;
	if (!BackupRead(h,(void*)&sid,20, &rv,FALSE,FALSE,&lpContext)) {
		goto FAIL;
	}
	if (rv < 2) {
		/* SUCCESS */
		(void)BackupRead(h,buffer,sizeof(buffer),&rv,TRUE,FALSE,&lpContext);
		CloseHandle(h);
		set_backup_privs(0);
		SetLastError(ERROR_SUCCESS);
		return 1;
	}

	if (rv != 20) {
		goto FAIL;
	}

	if (sid.dwStreamId != 1 || sid.dwStreamAttributes != 0
	|| sid.dwStreamNameSize > 0) {
		/* skip */
		BackupSeek(h, sid.dwStreamNameSize, 0,
				(void*)buffer, (void*)(buffer+8), &lpContext);
		BackupSeek(h, sid.Size.LowPart, sid.Size.HighPart,
				(void*)buffer, (void*)(buffer+8), &lpContext);
		goto NEXT_STREAM;
	}

	while (sid.Size.QuadPart > 0) {
		rv = 0;
		if (sid.Size.QuadPart < sizeof(buffer)) {
			n = sid.Size.QuadPart;
		} else {
			n = sizeof(buffer);
		}
		if (!BackupRead(h,buffer,n,&rv,FALSE,FALSE,&lpContext)) {
			goto FAIL;
		}
		r=rv;
		if (!r) break;
		if (!fout(ff, buffer, r)) {
			goto FAIL;
		}
	}
	goto NEXT_STREAM;
FAIL:
	r = GetLastError();
	(void)BackupRead(h,buffer,sizeof(buffer),&rv,TRUE,FALSE,&lpContext);
	CloseHandle(h);
	set_backup_privs(0);
	SetLastError(r);
	return 0;
}
Beispiel #5
0
/******************************************************************************
 * CKMPrivate_Utils::secureDeleteStreams()
 *
 * Parameters:  inFilename - [in] name of file with streams to delete
 *              inDeletePasses - [in] number of "cleaning" passes to make
 *
 * Returns:	    Nothing
 * Throws:		Nothing
 *
 * Description: Securely delete all streams belonging to the supplied
 *              file by overwriting them with 111s and 000s.
 *
 * Note:        Does not exist under Unix, which has no alternate stream support
 *****************************************************************************/
bool FileVEILOperationsImpl::secureDeleteStreams(const tscrypto::tsCryptoString& inFilename, int inDeletePasses)
{
	TSDECLARE_FUNCTIONExt(true);

#ifdef WIN32
	// if we aren't on an NT platform, bail out now (no streams to delete)
	//OSVERSIONINFO osvi;
	//ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
	//osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

	//if (! GetVersionEx ( (OSVERSIONINFO *) &osvi))
	//{
	//    return TSRETURN(("OK"),true);
	//}
	//else if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
	//{
	//    return TSRETURN(("OK"),true);
	//}

	int index;
	HANDLE hFile;
	BOOL bContinue;
	void * ctx = NULL;
	WIN32_STREAM_ID sid;
	DWORD dwRead, lo, hi;

	// open the file whose streams we want to delete
	if (INVALID_HANDLE_VALUE == (hFile = CreateFileA(inFilename.c_str(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)))
	{
		LogError("Unable to open the specified file.  " + inFilename);
		return TSRETURN_ERROR(("Invalid filename"), true);
	}

	// we have to build a list of named files to delete, and then close the
	// original file. The streams can't be written when the main file is open
	int streamCnt = 0;
	tscrypto::tsCryptoStringList streamList = CreateTsAsciiList();

	CryptoUtf16 streamName;
	tscrypto::tsCryptoString tmpStr;

	// read the first 20 bytes of the stream (all but the last field)
	while ((bContinue = BackupRead(hFile, (LPBYTE)&sid,
		sizeof(sid) - sizeof(WCHAR *), &dwRead, FALSE, FALSE, &ctx)) != FALSE)
	{
		// if we are done or there was no data read, break out
		if (!bContinue || !dwRead)
			break;

		// if this stream is named Alternate Data, delete it
		if (sid.dwStreamId == BACKUP_ALTERNATE_DATA && sid.dwStreamNameSize > 0)
		{
			// get the name of the stream (Wide-Char format)
			streamName.clear();
			streamName.resize(sid.dwStreamNameSize / sizeof(ts_wchar));

			BackupRead(hFile, (byte *)streamName.data(), sid.dwStreamNameSize, &dwRead, FALSE, FALSE, &ctx);

			if (wcslen(streamName.c_str()) >= 6 && wcscmp(&streamName[wcslen(streamName.c_str()) - 6], L":$DATA") == 0)
			{
				streamName.resize(streamName.size() - 6);
			}

			tmpStr = inFilename + streamName.toUtf8();
			streamList->push_back(tmpStr);
		}

		// seek to the end of this stream so we can check the next one
		BackupSeek(hFile, sid.Size.LowPart, sid.Size.HighPart, &lo, &hi, &ctx);
	}

	// free memory allocated by BackupRead and close the file
	BackupRead(hFile, (LPBYTE)&sid, 0, &dwRead, TRUE, FALSE, &ctx);
	CloseHandle(hFile);

	m_taskCount += streamCnt;

	// now go through the list we built and secureDelete each stream
	for (index = 0; index < streamCnt; index++)
	{
		// ignore exceptions and move on to the next one
		LOG(DebugInfo1, "CKMPrivate_Utils::secureDeleteStreams() securedelete stream " << streamList->at(index));
		if (!secureDeleteFile(streamList->at(index), inDeletePasses))
			return TSRETURN(("Returns ~~"), false);
		m_currentTask++;
	}

#endif /* WIN32 */
	return TSRETURN(("OK"), true);
}
Beispiel #6
0
/* Print out streams of a file */
int os_get_streams(char *full_path)
{
    HANDLE file_h; 
    WIN32_STREAM_ID sid;
    void *context = NULL;

    char stream_name[MAX_PATH +1]; 
    char final_name[MAX_PATH +1]; 

    DWORD dwRead, shs, dw1, dw2;


    /* Opening file */
    file_h = CreateFile(full_path, 
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS,
            NULL);

    if (file_h == INVALID_HANDLE_VALUE) 
    { 
        return 0;
    }


    /* Zeroing memory */
    ZeroMemory(&sid, sizeof(WIN32_STREAM_ID));

    /* Getting stream header size -- should be 20 bytes */
    shs = (LPBYTE)&sid.cStreamName - (LPBYTE)&sid+ sid.dwStreamNameSize;


    while(1)
    {
        if(BackupRead(file_h, (LPBYTE) &sid, shs, &dwRead, 
                    FALSE, FALSE, &context) == 0)
        {
            break;
        }
        if(dwRead == 0)
        {
            break;
        }

        stream_name[0] = '\0';
        stream_name[MAX_PATH] = '\0';
        if(BackupRead(file_h, (LPBYTE)stream_name, 
                    sid.dwStreamNameSize, 
                    &dwRead, FALSE, FALSE, &context))
        {
            if(dwRead != 0)
            {
                char *tmp_pt;
                snprintf(final_name, MAX_PATH, "%s%S", full_path, 
                        (WCHAR *)stream_name);
                tmp_pt = strrchr(final_name, ':');
                if(tmp_pt)
                {
                    *tmp_pt = '\0';
                }
                printf("Found NTFS ADS: '%s' \n", final_name);
                ads_found = 1;
            }
        }

        /* Getting next */			
        if(!BackupSeek(file_h, sid.Size.LowPart, sid.Size.HighPart, 
                    &dw1, &dw2, &context))
        {
            break;
        }
    }

    CloseHandle(file_h);
    return(0);
}