[New WTFBin]: IBM Personal Communications pcsnp.exe
59e5aaf4 opened this issue · 2 comments
-
Contributor Name: 59e5aaf4
-
Application/Executable: pcsnp.exe
-
SHA256 caa69ac524061e231b341b92995a9cbc2b4db81035cbef724695a175e9e6ae3f
-
WTF Behavior Description: Has a subprocess
cmd.exe /c mkdir c:\Temp
launched, possibly from other processes asS-1-5-18
likempnotify.exe
orlsass.exe
.- mpnotify.exe will launch
cmd.exe /c mkdir c:\Temp
- lsass.exe will launch
cmd.exe /c mkdir c:\Temp
- mpnotify.exe will launch
-
Link to Documentation of Behavior:
1 - The tool.
I don't know where to start. This binary is part of some https://www.ibm.com/support/pages/ibm-personal-communications IBM "Personal Communications" tool, some sort of SSH.IBM.EXE relying on java and .exe to do script-like jobs.
- As per vendor : "IBM® Personal Communications is a host communication and terminal emulation package for Microsoft™ Windows™. Now with full 64-bit architecture, it features virtual terminal (VT) emulation and systems network architecture (SNA) application support and provides a platform to access data and applications on different host systems. It is a component of IBM Host Access Client Package (HACP) and IBM Host Integration Solution."
It's commonly found on sysadmins workstations who work on any IBM thingies.
2 - The code.
pcsnp.exe
( has a lot of pcs*.exe
friends in C:\Program Files (x86)\ibm\Personal Communications\
) has a weird forced mkdir subcommand ( presumably written by Neelabh
int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
char CurrentProcessId; // al
char TickCount; // [esp+0h] [ebp-4h]
TickCount = GetTickCount();
GetEnvironmentVariable_PCOMM_Root();
system_mkdir_c_Temp_pcsnp_init_log(); // Make that system("mkdir ...") call
WriteLog((wchar_t *)L"cmdLine parse\n", TickCount);
if ( ParseCommandLine(lpCmdLine) )
{
ReadFile_wrapper(&logfile);
CryptProtectData_Neelabh_Credentials(&logfile); // Some fun
}
__RTDynamicCast();
CreateProcessA_tpam_exe(); // More fun
GetTickCount();
CurrentProcessId = GetCurrentProcessId();
WriteLog((wchar_t *)L"pcsnp(%d) %d sec\n\n", CurrentProcessId);
SetLastError(0);
return 0;
}
The first function does this : system("mkdir c:\\Temp");
, effectively causing a subprocess cmd.exe /c mkdir c:\Temp
to be launched.
wchar_t *system_mkdir_c_Temp_pcsnp_init_log()
{
system("mkdir c:\\Temp");
return wcscpy(pcsnp_init_log_path, L"c:\\Temp\\pcsnp_init.log");
}
3 - The behavior.
Sometimes, this is done from OTHER binaries than pcsnp.exe like mpnotify.exe ( at user login ? suspected since pcsnp parent is usually userinit.exe
), and on very rare occasions, by lsass.exe
, causing CrowdStrike to pop a LsassToChild
alert for valid reasons.
- mpnotify.exe will launch
cmd.exe /c mkdir c:\Temp
- lsass.exe will launch
cmd.exe /c mkdir c:\Temp
When this second, rare, behavior happens, CrowdStrike fires a LsassToChild alert stating : "Lsass launched a child process. If this child process is unexpected, it might indicate malware hijacked lsass to evade detection or dump credentials. Investigate the process tree."
- Please provide any images for additional evidence.
Correlation between these mkdir
commands and that tool being launched. Timestamps are missing but I swear it's really close.
IDA screenshot for fun and giggles; this appends forever to a log file (C:\Program Files (x86)\ibm\Personal Communications\private\pcsnp.log
) without any timestamps fksdjhfqkljh. While we're at it, it has the capability (and forcibly tries) to launch tpam.exe
, which I didn't find anywhere in my infra haha. So plant "tpam.exe
" in system32 and boom, magic persistence whenever some admin launches that IBM thingy or just opens a session. BRB filing papers to open a crime consulting company.
int CreateProcessA_tpam_exe() { // redacted for brevity // read that churchill memo on brevity, it's good.
WriteLog((wchar_t *)L"Tpam \n", v1);
result = CreateProcessA(0, (LPSTR)"tpam.exe
return WriteLog((wchar_t *)L"Tpam(%d) started\n", ProcessInformation.dwProcessId);
I still have NO idea why these mkdir
commands appear as children of other processes, but I couldn't find another binary containing that specific string.
4 - Why Neelabh
?
Why Neelabh
? Here it is, that string is used as a test vector for encryption with Crypt(Un)ProtectData
.
v7 = RegCreateKeyExW(HKEY_CURRENT_USER, aSoftwareIbmPer, 0, 0, 1u, 0xF003Fu, 0, &hKey, &dwDisposition);// Software\IBM\Personal Communications\CurrentVersion\Credentials
if ( !v7 && hKey && (dwDisposition == 1 || dwDisposition == 2) )
{
RegDeleteValueA(hKey, "Data");
/* here */
if ( CryptProtectData(&pDataIn, L"Neelabh", &pOptionalEntropy, 0, 0, 0, &pDataOut) ) {
if ( !RegSetValueExA(hKey, "Data", 0, 3u, pDataOut.pbData, pDataOut.cbData) ) {
if ( CryptUnprotectData(&pDataOut, 0, &pOptionalEntropy, 0, 0, 0, &v5) ) {
if ( !memcmp(v5.pbData, pDataIn.pbData, v5.cbData) && v5.cbData == pDataIn.cbData ) {
log((wchar_t *)L"Encryption validation success\n", v2); v10 = 1;
} else {
log((wchar_t *)L"Encryption validation failed\n", v2); v10 = 0;
} LocalFree(v5.pbData);
}
else
{ RegDeleteValueA(hKey, "Data"); v10 = 0;
( also gg )