How to disable encryption done by Wincrypt API - c++

I want to disable the encryption which is encrypted in Wincrypt API.
Please give me suggestions, how to do that, general sugestions are also welcomed
Below is the Code Samples from EncryptedMessage.cpp :
EncryptedMessage Encrypt( TextMessage& Msg, const KeyBlob& RecipientExchangeKeyBlob )
throw( CCryptoEngine::Exception )
{
CryptProvider CryptProvider = GetCryptoProvider();
CryptKey SessionKey = CreateSessionKey( CryptProvider );
CryptKey RecipientExchangeKey = ImportExchangeKey( CryptProvider,
RecipientExchangeKeyBlob );
KeyBlob SessionKeyBlob = CreateSessionKeyBlob( SessionKey, RecipientExchangeKey );
if( ! CryptEncrypt( SessionKey, 0, TRUE, 0,
Msg.Text(), &Msg.Size(), Msg.Capacity() ) )
throw CCryptoEngine::Exception( ResourceString( IDS_CREN_MSG_ENC_FAILED ) +
GetErrorMessageFromCode( GetLastError() ) );
KeyBlob SignatureBlob; //Empty signature
return EncryptedMessage( SessionKeyBlob, Msg, SignatureBlob );
}
Useful Code Snipped from another class Below:
CCryptoEngine::CryptProvider CCryptoEngine::
GetCryptoProvider()
throw( CCryptoEngine::Exception )
{
if( ! CryptProviderAllocator::IsAllocated( m_RSACryptProvider ) )
{
if( ! CryptAcquireContext( &m_RSACryptProvider, _T("CollabWorx SIM Client"),
MS_ENHANCED_PROV, PROV_RSA_FULL, 0 ) )
if( ! CryptAcquireContext( &m_RSACryptProvider, _T("CollabWorx SIM Client"),
MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET ) )
if( ! CryptAcquireContext( &m_RSACryptProvider, NULL, MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT ) )
throw CCryptoEngine::Exception(
"Your system may lack the required security capabilities.\n"
"Please make sure that Microsoft High Encryption Pack (128-bit strength) "
"is installed in your system.\n\nInformation for the support:\n"
+ GetErrorMessageFromCode( GetLastError() ) );
g_RSACryptProvider = m_RSACryptProvider;
}
return m_RSACryptProvider;
}

If you want to decrypt the encrypted message, you should use the CryptDecrypt function.
See MSDN document:
https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(Wincrypt%2FCryptDecrypt);k(CryptDecrypt);k(DevLang-C%2B%2B);k(TargetOS-Windows)&rd=true
Based on your code, you should use the same SessionKey as the one used in the Encrypt method to decrypt the encrypted message.

Related

Is it possible to read and write cookies using BHO in internet explorer

I am working an extension for Internet explorer to read network traffic using BHO in C++. My code is based on the following,
https://github.com/salsita/passthruapp
Is there a way that I can access cookies that are stored on the browser? I want to be able to read a cookie set for a particular domain and also store a cookie for the domain.
I used InternetGetCookieEx and InternetSetCookieEx. My goal was just to expire cookies so I had the following:
#define EXPIRED_COOKIE_DATE L"expires = Sat,01-Jan-2000 00:00:00 GMT"
void ExpireCookies( const CString& strUrl )
{
DWORD dwSize;
BOOL bResult = InternetGetCookieEx( strUrl, NULL, NULL, &dwSize, INTERNET_COOKIE_HTTPONLY, NULL );
if ( !bResult || dwSize <= 0 )
return;
TCHAR *lpszData = new TCHAR[dwSize];
LPCWSTR usrauth = NULL;
bResult = InternetGetCookieEx( strUrl, usrauth, lpszData, &dwSize, INTERNET_COOKIE_HTTPONLY, NULL );
if ( !bResult )
goto Exit;
{
CString cookieDataString( lpszData );
int nTokenPos = 0;
CString cookie = cookieDataString.Tokenize( _T( "; " ), nTokenPos );
while ( nTokenPos >= 0 )
{
int separator = cookie.Find( _T( '=' ) );
CString cookieName = cookie.Left( separator );
CString value = cookie.Mid( separator + 1 );
VERIFY( InternetSetCookieEx( strUrl, cookieName, EXPIRED_COOKIE_DATE, INTERNET_COOKIE_HTTPONLY, NULL ) );
cookie = cookieDataString.Tokenize( _T( "; " ), nTokenPos );
}
}
Exit:
SAFE_DELETE_ARR( lpszData );
}
Hope it helps you some!

How to AES CBC encryption Using cryptoAPI

I want to encrypt a file with AES CBC mode encryption, Using cryptoAPI functions and set my own key from the command-line (It my change in the code)
I imagine that the key (after change) will be 1a1dc91c907325c6 and tried in this form:
HCRYPTPROV hProv = NULL;
HCRYPTKEY hKey = NULL;
DWORD dwBlobLen;
PBYTE pbKeyBlob = NULL;
pbKeyBlob = (PBYTE)"1a1dc91c907325c6";
if(!CryptAcquireContext(&hProv, NULL,NULL, PROV_RSA_AES,CRYPT_VERIFYCONTEXT))
{
printf(" Error in AcquireContext 0x%08x \n",GetLastError());
}
if (!CryptImportKey(hProv,pbKeyBlob,sizeof(pbKeyBlob),0,CRYPT_EXPORTABLE,&hKey ))
{
printf("Error 0x%08x in importing the Des key \n",GetLastError());
}
but CryptImportKey failed
I don't know how to use cryptoAPI functions and It's parameters
I tested some other codes and change the parameters or function's call's order for about 2 weeks but I wasn't able to do this
Please help me [a big help :)]
Thank you
You should do it like this:
if( ::CryptAcquireContext( &m_hCryptoProvider, NULL, NULL/*Default*/, PROV_RSA_AES, CRYPT_VERIFYCONTEXT ) )
{
//Hash Password
// CALG_SHA1 OK
// CALG_AES_128 / CALG_AES_256 => error
if( ::CryptCreateHash( m_hCryptoProvider, CALG_SHA1, 0, 0, &m_hHashPassword ) )
{
// Hash for the password.
if( ::CryptHashData( m_hHashPassword, (BYTE *)password, (DWORD) _tcslen(password) * sizeof(TCHAR), 0 ) )
{
// Session key from the hash
if( ::CryptDeriveKey( m_hCryptoProvider, CALG_AES_256, m_hHashPassword, CRYPT_CREATE_SALT, &m_hCryptKey ) )
{
TRACE( TEXT("Crypto-API OK\n") );
return ERROR_SUCCESS;
}
else
{
TRACE( TEXT("Error in CryptDeriveKey\n") );
}
}
else
{
TRACE( TEXT("Error in CryptHashData\n") );
}
}
else
{
TRACE( TEXT("Error in CryptCreateHash\n") );
}
}
else
{
TRACE( TEXT("Error in CryptAcquireContext\n") );
}
After that you need to use CryptEncrypt/CryptDecrypt to do encode/decode data.

How to determinate if my application is running under SYSTEM account or not?

How could I decide if my application is running under LocalSystem Account or not? Is there an easy way to do that?
Thanks!
Thanks for your help, but I might have found a way. Not the best, I know, but it works.
BOOL CheckIfRunningAsSYSTEM( VOID )
{
DWORD i, dwSize = 0, dwResult = 0;
HANDLE hToken;
PTOKEN_USER Ptoken_User;
// Open a handle to the access token for the calling process.
if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
{
printf( "OpenProcessToken Error %u\n", GetLastError() );
return FALSE;
}
// Call GetTokenInformation to get the buffer size.
if ( !GetTokenInformation( hToken, TokenUser, NULL, dwSize, &dwSize ) )
{
dwResult = GetLastError();
if ( dwResult != ERROR_INSUFFICIENT_BUFFER )
{
printf( "GetTokenInformation Error %u\n", dwResult );
return FALSE;
}
}
// Allocate the buffer.
Ptoken_User = ( PTOKEN_USER )GlobalAlloc( GPTR, dwSize );
// Call GetTokenInformation again to get the group information.
if ( !GetTokenInformation( hToken, TokenUser, Ptoken_User, dwSize, &dwSize ) )
{
printf( "GetTokenInformation Error %u\n", GetLastError() );
return FALSE;
}
LPWSTR SID = NULL;
if ( !ConvertSidToStringSidW( Ptoken_User->User.Sid, &SID ) )
{
printf( "\nConvertSidToStringSidW failed. Error = %d", GetLastError() );
return FALSE;
}
else printf( "\nConvertSidToStringSidW succeeded." );
if ( _wcsicmp( L"S-1-5-18", SID ) == 0 ) printf( "\nRunning under SYSTEM" );
else printf( "\nNOT running under SYSTEM" );
if ( Ptoken_User ) GlobalFree( Ptoken_User );
return TRUE;
}//CheckIfRunningAsSYSTEM

How to impersonate a user from a service correctly?

I'm working a service, which should impersonate the logged on user.
My code so far, with basic error handling:
// get the active console session ID of the logged on user
if ( !WTSQueryUserToken( WTSGetActiveConsoleSessionId(), &hToken ) )
{
ShowErrorText( "WTSQueryUserToken failed.", GetLastError( ), true );
return;
}
HANDLE hDuplicated;
// duplicate the token
if ( !DuplicateToken( hToken, SecurityImpersonation, &hDuplicated ) )
{
ShowErrorText( "DuplicateToken failed.", GetLastError( ), true );
}
else
{
ShowErrorText( "DuplicateToken succeeded.", 0, true );
}
// impersonate the logged on user
if ( !ImpersonateLoggedOnUser( hToken ) )
{
ShowErrorText( "ImpersonateLoggedOnUser failed.", GetLastError(), true );
return;
}
// retrieve the DC name
if ( !GetPrimaryDC( DC ) )
{
ShowErrorText( "GetPrimaryDC failed.", 0, true );
}
PROFILEINFO lpProfileInfo;
ZeroMemory( &lpProfileInfo, sizeof( PROFILEINFO ) );
lpProfileInfo.dwSize = sizeof( PROFILEINFO );
lpProfileInfo.lpUserName = CurrentUser;
// get type of profile. roaming, mandatory or temporary
int ret = GetTypeOfProfile();
if ( ret == 2 )
{
// if roaming profile get the path of it
if ( !GetRoamingProfilePath( DC, CurrentUser, RoamingProfilePath ) )
{
ShowErrorText( "Failed to retrieve roaming profile path.", GetLastError(), true );
}
}
if ( RevertToSelf( ) )
{
ShowErrorText( "Impersonation ended successfully.", 0, true );
}
if ( !LoadUserProfile( hDuplicated, &lpProfileInfo ) )
{
ShowErrorText( "LoadUserProfile failed.", GetLastError(), true );
}
else
{
ShowErrorText( "LoadUserProfile succeeded.", 0, true );
}
//do some stuff
if ( !UnloadUserProfile( hDuplicated, lpProfileInfo.hProfile ) )
{
ShowErrorText( "UnloadUserProfile failed.", GetLastError( ), true );
}
else
{
ShowErrorText( "UnloadUserProfile succeeded.", 0, true );
}
if ( !ImpersonateLoggedOnUser( hToken ) )
{
ShowErrorText( "ImpersonateLoggedOnUser failed.", GetLastError( ), true );
return;
}
According to MSDN:
When a user logs on interactively, the system automatically loads the user's profile. If a service or an application impersonates a user, the system does not load the user's profile. Therefore, the service or application should load the user's profile with LoadUserProfile.
Services and applications that call LoadUserProfile should check to see if the user has a roaming profile. If the user has a roaming profile, specify its path as the lpProfilePath member of PROFILEINFO. To retrieve the user's roaming profile path, you can call the NetUserGetInfo function, specifying information level 3 or 4.
Upon successful return, the hProfile member of PROFILEINFO is a registry key handle opened to the root of the user's hive. It has been opened with full access (KEY_ALL_ACCESS). If a service that is impersonating a user needs to read or write to the user's registry file, use this handle instead of HKEY_CURRENT_USER. Do not close the hProfile handle. Instead, pass it to the UnloadUserProfile function.
If i use my code as it is now, then it works. However is it a little strange, because first i have to impersonate the logged on user, and then end the impersonation, to Load the users profile. If i don't end the impersonation then LoadUserProfile will fail with error 5 ( Access denied ). And after LoadUserProfile succeeded i should impersonate the user again?
So my question is, this meant to be done this way, or i am doing something wrong?
Another question is, that if LoadUserProfile succeeded i could use hProfile as a Handle to the logged on users registry. Question is how? Because to use RegOpenKeyEy and RegSetValueEx i need to pass a HKEY, not a HANDLE. So how can i use this Handle?
Thank!
You don't need to call ImpersonateLoggedOnUser() since you are passing the user's token to LoadUserProfile(). Call ImpersonateLoggedOnUser() only if you need to call APIs that do not allow you to pass a user token to them.
If you read the rest of the LoadUserProfile() documentation, it says:
The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges.
By impersonating the user you are trying to load a profile for, you are likely losing those privileges. So don't impersonate the user.
Update: Try something like this:
// get the active console session ID of the logged on user
DWORD dwSessionID = WTSGetActiveConsoleSessionId();
if ( dwSessionID == 0xFFFFFFFF )
{
ShowErrorText( "WTSGetActiveConsoleSessionId failed.", GetLastError( ), true );
return;
}
if ( !WTSQueryUserToken( dwSessionID, &hToken ) )
{
ShowErrorText( "WTSQueryUserToken failed.", GetLastError( ), true );
return;
}
// duplicate the token
HANDLE hDuplicated = NULL;
if ( !DuplicateToken( hToken, SecurityImpersonation, &hDuplicated ) )
{
ShowErrorText( "DuplicateToken failed.", GetLastError( ), true );
CloseHandle( hToken );
return;
}
// retrieve the DC name
if ( !GetPrimaryDC( DC ) )
{
ShowErrorText( "GetPrimaryDC failed.", 0, true );
CloseHandle( hDuplicated );
CloseHandle( hToken );
return;
}
PROFILEINFO lpProfileInfo;
ZeroMemory( &lpProfileInfo, sizeof( PROFILEINFO ) );
lpProfileInfo.dwSize = sizeof( PROFILEINFO );
lpProfileInfo.lpUserName = CurrentUser;
// get type of profile. roaming, mandatory or temporary
USER_INFO_4 *UserInfo = NULL;
int ret = GetTypeOfProfile();
if ( ret == 2 )
{
// if roaming profile get the path of it
if ( NetUserGetInfo( DC, CurrentUser, 4, (LPBYTE*)&UserInfo) != NERR_Success )
{
ShowErrorText( "NetUserGetInfo failed.", 0, true );
CloseHandle( hDuplicated );
CloseHandle( hToken );
return;
}
lpProfileInfo.lpProfilePath = UserInfo->usri3_profile;
}
if ( !LoadUserProfile( hDuplicated, &lpProfileInfo ) )
{
ShowErrorText( "LoadUserProfile failed.", GetLastError(), true );
if ( UserInfo )
NetApiBufferFree(UserInfo);
CloseHandle( hDuplicated );
CloseHandle( hToken );
return;
}
if ( UserInfo )
NetApiBufferFree(UserInfo);
ShowErrorText( "LoadUserProfile succeeded.", 0, true );
//do some stuff
if ( !UnloadUserProfile( hDuplicated, lpProfileInfo.hProfile ) )
{
ShowErrorText( "UnloadUserProfile failed.", GetLastError( ), true );
}
else
{
ShowErrorText( "UnloadUserProfile succeeded.", 0, true );
}
CloseHandle( hDuplicated );
CloseHandle( hToken );
As for the Registry, the hProfile handle is the opened HKEY for the user's HKEY_CURRENT_USER tree. Simpy type-cast it from HANDLE to HKEY when passing it to Registry API functions. It is already opened, so you do not need to call RegOpenKeyEx() to open that same key again, but you can use it as the root key when creating/opening subkeys, or reading/writing values in the root key.

How to enable a DHCP subnet through DhcpSAPI

I'm writing a module to manage a DHCP server co-located with the service in which the module exists.
I have code in place using the DHCP Server API which is able to create a subnet and add DHCP reservations. What I don't seem to be able to do is actually enable/activate the subnet scope.
I had assumed that DhcpSetSubnetInfo( ) would do the job with the SubnetState field of the DHCP_SUBNET_INFO structure set to DhcpSubnetEnabled however this seems to have no effect.
Scanning through the rest of the DHCP Server API I can't see any other methods for configuring subnets/scopes.
Has anyone managed to do this?
Thanks for your help.
Nick.
Edit:
static bool enableSubnet(
const std::wstring& server,
DWORD dwSubnet
)
{
LPDHCP_SUBNET_INFO pInfo = NULL;
DWORD res = DhcpGetSubnetInfo(
server.c_str( ),
dwSubnet,
&pInfo
);
if ( res != ERROR_SUCCESS )
{
DhcpRpcFreeMemory( pInfo );
return false;
}
if ( pInfo->SubnetState == DhcpSubnetEnabled )
{
DhcpRpcFreeMemory( pInfo );
return true;
}
DHCP_SUBNET_INFO info( *pInfo );
info.SubnetState = DhcpSubnetDisabled;
res = DhcpCreateSubnet( server.c_str( ), dwSubnet, &info );
DhcpRpcFreeMemory( pInfo );
if ( res != ERROR_SUCCESS )
{
return false;
}
res = DhcpGetSubnetInfo(
server.c_str( ),
dwSubnet,
&pInfo
);
if ( res != ERROR_SUCCESS )
{
DhcpRpcFreeMemory( pInfo );
return false;
}
bool retVal = ( pInfo->SubnetState == DhcpSubnetEnabled );
if ( !retVal )
{
std::wcerr << L"Failed to enable subnet";
}
DhcpRpcFreeMemory( pInfo );
return retVal;
}
Debugging the code, all of the DhcpXX functions pass, but the function returns false when checking:
bool retVal = ( pInfo->SubnetState == DhcpSubnetEnabled );
Have you tried calling DhcpCreateSubnet with the DhcpSubnetEnabled flag set as noted above? Possibly your code already does this - post the part that fails to create and enable the subnet.
Make sure you check all your Windows APIs calls for errors too. Again, some code would help identify what might be failing.