I discovered that it is possible to extract the hard-coded strings from a binary.
For example the properties view of Process Explorer displays all the string with more than 3 characters.
Here is the code of a simple executable that I wrote to simply test it:
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
_TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
_TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
for (int i= 0; i<argc; i++) {
if (0 == _tcscmp(argv[i],hiddenString1)) {
_tprintf (_T("The guid argument is correct.\n")); }
else if (0 == _tcscmp(argv[i],hiddenString2)) {
_tprintf (_T("Do something here.\n")); }
}
_tprintf (_T("This is a visible string.\n"));
//Keep Running
Sleep(60000);
return 0;
}
The strings can clearly be extracted from the corresponding executable:
I think that it is a little too easy to find the strings.
My questions are:
How to simply hide hiddenString1 or hiddenString2 in the
executable?
Is there a more secure
way to use "cheat code" than with
some obscure hidden input?
Welcome to the wider world of defensive programming.
There are a couple of options, but I believe all of them depend on some form of obfuscation; which, although not perfect, is at least something.
Instead of a straight string value you can store the text in some other binary form (hex?).
You can encrypt the strings that are stored in your app, then decrypt them at run time.
You can split them across various points in your code, and reconstitute later.
Or some combination thereof.
Bear in mind, that some attacks go further than looking at the actual binary. Sometimes they will investigate the memory address space of the program while it's running. MS came up with something called a SecureString in .Net 2.0. The purpose being to keep the strings encrypted while the app is running.
A fourth idea is to not store the string in the app itself, but rather rely on a validation code to be submitted to a server you control. On the server you can verify if it's a legit "cheat code" or not.
There are many ways to obscure data in an executable. Others here have posted good solutions -- some stronger than others. I won't add to that list.
Just be aware: it's all a cat-and-mouse game: it is impossible to guarantee that nobody will find out your "secret".
No matter how much encryption or other tricks you use; no matter how much effort or money you put into it. No matter how many "NASA/MIT/CIA/NSA" types are involved in hiding it.
It all comes down to simple physics:
If it were impossible for any user to pull out your secret from the executable and "unhide" it, then the computer would not be able to unhide it either, and your program wouldn't be able to use it. Any moderately skilled developer with enough incentive will find the way to unhide the secret.
The moment that you have handed your executable to a user, they have everything they need to find out the secret.
The best you can hope for is to make it so hard to uncover the secret that any benefits you can get from knowing the secret become not worth the hassle.
So, it's OK to try to obscure the data if it's merely "not-nice" for it to be public, or if the consequences of it becoming public would just be "inconvenient". But don't even think of hiding in your program "the password to your master client database", a private key, or some other critical secret. You just can't.
If you have truly critically secret information that your program will somehow need but should NEVER become public information (like a private key), then you will need to have your program talk to a remote server under your control, apply appropriate authentication and authorization controls (that is, make sure only the approved people or computers are able to make the request to the server), and have that server keep the secret and use it.
The simplest way is to encrypt them with something trivial like xor or rot-13, and then decrypt them on the fly when they're used. That will eliminate casual viewing of them, but it won't stop anyone with much experience at reversing.
In addition to those methods Chris mentions you could also use a hashing algorithm. If all you want to do is check if the correct ID was specified you don't actually need to store the whole ID in your program.
Create a hash (MD5, SHA, etc) of the string/password/id you want to compare against, maybe add a 'salt' value to it. Store this in your program
When the program is run, do the same algorithm on the input string/password/id and compare the two hashes to see if they match.
This way the actual text is never stored in your program and they cannot reverse engineer your program to find out what the original text was because hash algorithms are one-way only.
There are URLs for http requests that I would like to hide too.
If your app is making the request, there is no point hiding this. Running an app like fiddler, http analyzer, or one of dozens of other free and readily available methods will show all the traffic your app is creating.
Here is the method I use for this purpose. First, I use the the Strings tool by Sysinternals to display the strings in an EXE or DLL.
I then use the following small tool (see article) to replace these strings with a scrambled array of characters stored as an arithmetic expression: for example: instead of the string:
"this is a test"
I will place the following code: (which is automatically generated by this tool)
WCHAR T1[28];
T1[22] = 69;
T1[15] = 121 - 17;
T1[9] = L':' + -26;
T1[12] = L't' - 1;
T1[6] = 116 - 1;
T1[17] = 117 - 12;
T1[3] = 116 - 1;
T1[14] = L'' - 3;
T1[13] = L'w' - 3;
T1[23] = 69;
T1[26] = L'Y' + 3;
T1[19] = 111 + 0;
T1[21] = L'k' - 34;
T1[27] = L'\\' - 8;
T1[20] = L'B' + 32;
T1[4] = 42 + -10;
T1[25] = L'm' - 17;
T1[16] = L'H' + 18;
T1[18] = L'A' + 56;
T1[24] = 68;
T1[1] = 105 - 1;
T1[11] = L'k' - 6;
T1[10] = 66 + 50;
T1[2] = 105;
T1[0] = 117 - 1;
T1[5] = L'k' - 2;
T1[8] = 89 + 8;
T1[7] = 32;
There are many solutions to this problem and none of them (including mine) is perfect, however there are ways to scramble, disguise, and hide the sensitive strings. You can of course encrypt them and decrypt during runtime (see this article), but I find more important to make these string disappear among the bits and bytes of the executable file and it works. After running my tool, you won't find "this is a test" in the executable file.
Will all your secret codes be GUIDs or was that just an example?
Perhaps store your secret as a binary guid:
const GUID SecretGuid =
{ 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };
Then convert your supplied guid from string to binary format and compare the two binary guids.
If there's a specific string you don't want people to be able to see, then encrypt it and decrypt at runtime.
If you don't want people to see your GUID, then construct it from bytes, rather than constructed from a string:
const GUID SecretGuid =
{ 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };
The best you can do is to code your password or other string that you want to hide as char array. For example:
std::string s1 = "Hello"; // This will show up in exe in hex editor
char* s2 = "World"; // this will show up in exe in hex editor
char s3[] = {'G', 'O', 'D'}; // this will not show up in exe in hex editor.
Related
To anyone that can help Please,
(My operating system is Windows XP)
I have looked on the this forum but have not found a similair answer that I could use or adapt to suite this particular situation. I will try to explain (I apologise in advance if my question seems confusing)
I am constructing a batch file that will call a C++ program (.exe) The C++ program is hard coded to the C: drive. By the way I did not write the C++ program as I am incapable of writing in C++ but would like to exchange the C: in C++ for what would be in batch %SystemDrive%. The line of code in C++ reads as follows:
SetSfcFileException(0, L"c:\\windows\\system32\\calc.exe",-1);
// Now we can modify the system file in a complete stealth.
}
The bit of code I would like to alter in the above code is C: or "C" to change it to %systemDrive% but in C++ code language, in effect change the hard coded part of the C++ program to read a System path variable within XP.
I have also looked elsewhere on the net but have not found a suitable answer as I do Not want to break the C++ code you see.
The C++ code was obtained from the folowing website written by Abdellatif_El_Khlifi:
https://www.codeproject.com/Articles/14933/A-simple-way-to-hack-Windows-File-Protection-WFP-u
Many Thanks for any help given,
David
The search term you should be looking for is Known Folders.
Specifically, calling SHGetKnownFolderPath() with the FOLDERID_System identifier, one of the many IDs found here.
That's for Vista or better. For earlier than that (such as XP), you have to use CSIDL values, CSIDL_SYSTEM (see here for list) passed into SHGetFolderPath().
You can still use the pre-Vista ones but I think they're just thin wrappers around the newer ones.
This is the simplest console application I could come up with that shows this in action (Visual Studio 2019):
#include <iostream>
#include <shlobj_core.h>
#include <comutil.h>
int main()
{
PWSTR path = NULL;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_System, 0, NULL, &path);
_bstr_t bstrPath(path);
std::string strPath((char*)bstrPath);
std::cout << "Path is '" << strPath << "'\n";
}
and the output on my system is:
Path is 'C:\WINDOWS\system32'
This is not really answering my own question, well it is but in a alternative manner, many ways to skin a cat so to speak!
Here is one encouraging bit of news though I have stumbled across the very thing I need called WFPReplacer, it is a commandline windows utility that pretty well does what I want & generally in the same manner. it disables WFP for both singular files & can be used for wholesale switching off of WFP if the right file is replaced. All I need to do is write a batch file as a front end to back up the system files I want to disable use WFPReplacer.exe. So if in the event of the proceedings the routine gets stuffed I can revert back to the backed up files. I think this program uses the same type of embedded coding but is written in Delphi/pascal, it is called Remko Weijnen's Blog (Remko's Blog) "replacing Wfp protected files".
I generally like to leave whatever I am doing on a positive note. So just in case someone else lands on this forum & is trying to accomplish a similair exercise here is the code that one can compile (This is not my code it belongs to Remko Weijnen's Blog (Remko's Blog)) Please be advised it is NOT C++ it is a commandline exe Delhi/Pascal found at this link, so all credits belong to him. The link is:
https://www.remkoweijnen.nl/blog/2012/12/05/replacing-wfp-protected-files/
DWORD __stdcall SfcFileException(RPC_BINDING_HANDLE hServer, LPCWSTR lpSrc, int Unknown)
{
RPC_BINDING_HANDLE hServerVar; // eax#2
int nts; // eax#6
__int32 dwResult; // eax#7
DWORD dwResultVar; // esi#9
int v8; // [sp+8h] [bp-8h]#1
int v9; // [sp+Ch] [bp-4h]#1
LOWORD(v8) = 0;
*(int *)((char *)&v8 + 2) = 0;
HIWORD(v9) = 0;
if ( !hServer )
{
hServerVar = _pRpcHandle;
if ( !_pRpcHandle )
{
hServerVar = SfcConnectToServer(0);
_pRpcHandle = hServerVar;
if ( !hServerVar )
return 0x6BA; // RPC_S_SERVER_UNAVAILABLE
}
hServer = hServerVar;
}
nts = SfcRedirectPath(lpSrc, (int)&v8);
if ( nts >= 0 )
dwResult = SfcCli_FileException((int)hServer, v9, Unknown).Simple;
else
dwResult = RtlNtStatusToDosError(nts);
dwResultVar = dwResult;
MemFree(v9);
return dwResultVar;
}
Also as one further warning (Unless you know what you are doing!!!) do not attempt to use this program, ALWAYS ALWAYS ALWAYS backup your system files before deletion or alteration.
What this program will do is disarm WFP for 60 seconds whilst you intercange or amend your files. Example usage for example is:
WfpReplacer.exe c:\windows\Notepad.exe (Errorlevel true or false will be produced on execution).
Best Regards
David
First off, I'm still relatively new working with smart cards and I don't know exactly how is data stored and which data is protected on a smart card.
I'm trying to read my student identification smart card which is PIN protected. I've been programming in C++ with default windows smart card library (winscard.lib).
I've successfully read ATR header but as far as I know, ATR header contains information on how to communicate with reader, not user information.
I've tried reading binary from the card and but APDU always returns 6E 00 which indicates "Class not supported" or "Wrong instruction". Here is the code:
switch(dwProtocol)
{
case SCARD_PROTOCOL_T0:
{
pioSendPci = *SCARD_PCI_T0;
break;
}
case SCARD_PROTOCOL_T1:
{
pioSendPci = *SCARD_PCI_T1;
break;
}
default:
{
printf("Detecting protocol failed!");
printf("Press <ENTER> key to terminate!\n");
nResponse = getchar();
lRet = SCardReleaseContext(hContext);
return -1;
}
}
lRet = SCardTransmit(hCard,
&pioSendPci,
(LPCBYTE)&cmdRead,
sizeof(cmdRead),
NULL,
(LPBYTE)&recvbuffer,
&atrLen);
printf("APDU return code:\n");
printf("=================\n");
for(i=0; i<2; i++)
{
printf("%02X ", recvbuffer[i]);
}
printf("\n");
if(lRet!=SCARD_S_SUCCESS)
{
printf("Transmission failed! ErrorCode = 0x%08X\n",lRet);
printf("Press <ENTER> key to terminate!\n");
nResponse = getchar();
lRet = SCardReleaseContext(hContext);
return -1;
}
Where cmdRead is as following:
BYTE cmdRead[] = { 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0xFF };
What could be wrong? Do I need to verify the card first in order to read binary? Is read binary right function to read basic data like student id?
Without a specification of the student application on the card, this is a lengthy and boring process.
Assumed that you have a file system on the card (as opposed to a java card) you need to know, in which file the user data is stored, so that you can SELECT the appropriate file before issuing the READ BINARY pr READ RECORD if its a record-oriented file. You can try to find the correct file ID by trial and error, but... Note, that on smart cards the access conditions are defined with very fine granularity, so there may be files, which can be read without any authentication, and on the other extreme, there may be files only readable after having established a secure channel to be used via secure messaging (encrypted and MAC-Protected command and or response).
I can think of two reasons why the card returns 6E00.
The currently selected application is the card manager or any other applet aside from the one you want to use. You can try to perform a SELECT AID command before sending the READ command. However, you should know the instance AID of the applet you want to select to do so.
The file you are trying to read is protected by secure messaging and your APDU command should be encrypted/MACed which would change the CLA byte to '0C' for example. However, you need to establish a secure channel first before you can do this.
Like #guidot said, this will be very difficult without a specification.
First of all, as #guidot mentioned it's boring process. Not only you have complete information on javacards, but also you should know how to something like hack a smart card, because you don't have any card vendor specification and probably they use security on their card which you should know the keys.
But for your information, according to ISO 7816-4 0x6E00 means "Class not supported". You can check complete list of APDU responses in here.
The class (CLA) byte is usually 0x00, 0xA0, 0xC0 or 0xF0 and sometimes masked with 0x0C that indicates Secure Messaging on some cards.
To reach data inside applet firewall you should select that applet and applet selection occurs when the JCRE(Java Card Runtime Environment) receives a select APDU whose data match the AID of the applet.
And if there be an installed security domain, then you should have those security keys in order to reach a successful applet selection.
To have a list of APDU commands communicating with the card reader check this link.
There's lots of information here about writing a smart card library in C++ , which uses WinSCard.dll to communicate with the reader.
Also this link is about file system structure in java card which would be useful if the applet stores its data in files.
and this link is an example of selecting a file in javacard.
If you want to go further through java card applet implementation, here's a guide on how to implement a java card applet.
Note that, don't forget to read most important existing document like Global platform and ISO 7816.
As Chooch said : In JAVA card ,
1. You should follow AID selection then
2. since you are reader Binary file , select binary EF
2a).Since you are using P1 00 i hope You already selected the particular EF.
Note : Even though i feel your command is wrong to read Binary data in ISO 7816/ ISO 14443 Smartcard .
else AS ISO 7816 4 :
Reader binary should be :
CLA INS 00 BO
P1 - Short File ID : MSB should be 1 : ur SID is 3 : It should be :83
P2 - should be Offset / Start Byte : eg : from 0 means : 00 if it is in between 10 : 0A
Le - should be No of bytes you want to read : eg 20 bytes means : 14
So command should be : 00 B0 83 14 0A : that is it. No need more bytes to read Binary file . if you already selected EF file Insted of 83 you can give 00:
Note : This is considers you dont have security conditions. If you have security condition you have to satisfy that before you read this.
I use C++, Qt 4.8.5, Visual Studio 2010. I'd like to create Windows GUI application which downloads some web pages. Note that my program is built in 32 bit mode and should be run in 32 and 64 bit Windows environment. I don't need to use Qt webkit. I need to analyze web pages. But the problem is character encoding. What charset auto-detection C/C++ library can be used in the case of absent charset information? MLang can't be used, because it is COM based. Extreme accuracy of detection is not required. I will prefer simple API and simple Windows friendly build instructions.
When there is no information about the encoding, the only way is to convert the data using many encodings and choose the best result. Evaluation of the result depends on your goal. For example, this function tries to choose between CP1251 and UTF-8 encodings assuming that the data represents text in Russian:
QString detect_encoding(const QByteArray &array) {
QString alphabet = QString::fromUtf8("АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя");
QString try_utf = QString::fromUtf8(array);
QString try_win = QTextCodec::codecForName("cp1251")->
toUnicode(try_utf.toLatin1());
int count_utf = 0, count_win = 0;
for(int i = 0; i < try_utf.length(); i++) {
if (alphabet.contains(try_utf[i])) {
count_utf++;
}
}
for(int i = 0; i < try_win.length(); i++) {
if (alphabet.contains(try_win[i])) {
count_win++;
}
}
if (count_win > count_utf) {
return try_win;
} else {
return try_utf;
}
}
There are quite few encodings that can represent Russian. You only need to add them to the comparation. The same approach should work for any language or combination of several languages, you just need to change the alphabet setting and encodings. (I advise to refactor this function. In current state it's just an illustration rather than a piece of production code.)
When there is no specific target language, decoding data without information about encoding is hardly possible. Also arbitrary page can contain some special symbols that can confuse detector. There is no universal way. I wish every site used UTF-8.
I have been thinking to implement the following program, just out of curiosity and learning experience. I want to write a program for password protecting a folder, so you can only open the folder after entering the correct password. I know this is specific to the operation system, so let it be Windows. I guess this is only possible in C++, but if it is also possible in plain C# or Java(which I doubt), then please tell me.
Could someone point me in the right direction? Thanks in advance!
Best regards, Petar
If you want a bulletproof protection of your files, then just protecting access to the folder is not enough, you'd have to encrypt them and there're secure containers and file system encyptions on the market.
If it does not need to be high security, you can hook into Windows I guess. You'll especially need to hook into the directory listing functions, like FindFirstFile, FindNextFile and OpenFile also probably (and into their derivates like FindFirstFileW) and maybe some others.
You do that by redirecting calls to kernel32.dll to your custom functions, see a little code example below which I found on the internet:
unsigned char Store[10];
//redirect FindNextFileW to your custom function
void HookAPI()
{
DWORD OldProtect, NewProtect = PAGE_EXECUTE_READWRITE;
HMODULE hmod = GetModuleHandle("Kernel32.dll");
long pa = (long)GetProcAddress(hmod,"FindNextFileW");
long pa2 = (long)MyFindNextFile;
long dAddr = pa2 - pa - 5;
unsigned char *p = (unsigned char *)pa;
unsigned char *p2 = (unsigned char *)(&dAddr);
VirtualProtect((void *)pa,5,NewProtect,&OldProtect);
for (int i=0;i<5;i++)
Store[i] = p[i];
p[0] = (unsigned char)0xE9;
for (int i=0;i<4;i++)
p[i + 1] = p2[i];
VirtualProtect((void *)pa,5,OldProtect,&NewProtect);
}
void UnHookAPI()
{
DWORD OldProtect, NewProtect = PAGE_EXECUTE_READWRITE;
HMODULE hmod = GetModuleHandle("Kernel32.dll");
long pa = (long)GetProcAddress(hmod,"FindNextFileW");
unsigned char *p = (unsigned char *)pa;
VirtualProtect((void *)pa,5,NewProtect,&OldProtect);
for (int i=0;i<5;i++)
p[i] = Store[i];
VirtualProtect((void *)pa,5,OldProtect,&NewProtect);
}
BOOL WINAPI MyFindNextFile(HANDLE hFindFile,LPWIN32_FIND_DATAW lpFindFileData)
{
UnHookAPI();
BOOL ans = FindNextFileW(hFindFile, lpFindFileData);
//your logic here, display password prompt to user e.g.
HookAPI();
return ans;
}
What you want to do can also be done with Java (JNI) or C# (pinvoke), but it'd be a real detour. I'd use something which can be compiled to native code.
Edit:
Aoi Karasu provided a link to a post which suggests to use a FileSystemFilterDriver, which is probably the best concept to realize the application in question.
An idea from the top of my head for a "simple" implementation.
The idea is to use windows authentication to create such protected folders.
Your application can generate a user for each encrypted folder F.
So for folder Fi you will generate user Ui with password Pi.
Also, for each Fi your application will have to make sure that ONLY Ui have access to it, and that no one can add access to it. Also, encrypt the files using window's encryption in NTFS.sys (there should be a simple function to encrypt the files in windows API, can't remember its name).
Now, if someone wants to access Fi you will popup a messagebox asking for the password, if they are right (you can use AccessCheck()) you can open explorer with Ui credentials pointing to Fi OR add Ui credentials to the user (in this case you will have to remove them at some point, so it could be tricky).
Windows (NTFS) supports "junction points". These are entries in the file system that tell Windows to execute a bit of code. A common type of junction point is the hardlink to another file or folder. However, you can add other types with matching drivers.
In your case, your encrypted folders could really be junction points that work like secured hardlinks. Yo only resolve the hardlink for authorized users. Because this works at NTFS kernel level, you don't need to worry about the million different file functions that exist in the different layers of Windows.
Using C++, I would like to use a command/class to get the latency time from pinging a host to use in my program. I tried using the ping command but there was no easy way to gather the time since its included with other statistical information. I was hoping for an easier approach.
The ping tool is usually implemented in C and works by sending ICMP Echo request packets over a raw socket,. The system time is recorded -- usually with gettimeofday on under posix -- when the Echo request is made and again when an Echo reply (if any) is received to determine the round-trip time. You can put the same functionality in your C++ application using sockets.
Otherwise, extracting the information from a ping system call is probably easier than you think. The key is to open a pipe to allow reading of the standard output of the ping command (see popen or _popen). A regular expression (e.g. "time=([0-9]*)") could be used to pluck out the desired data. If you don't have a regex library available, then extracting this data only requires fairly trivial string manipulation. The STL string class provides several algorithms that may be of use.
if you don't like regexes you can always loop through the output, looking for t followed by i followed by m followed by e followed by = by just stepping through the output string one piece at a time. store the pointer to the char after =, then step through futher and replace the next space by a zero. you now have a string with the latency, converting to a number can be done with the existing conversion functions.
e.g. if the output is in char* output with length stored in unsigned int length and the matched string needs to go in char* match...
for(unsigned int i = 4; i < length; ++i)
{
if(output[i] == '=')
{
if((output[i-4] = 't') && (output[i-3] = 'i') && (output[i-2] = 'm') && (output[i-1] = 'e'))
{
match = &(output[i+1]);
while(output[i] != ' ') ++i;
output[i] = 0;
break;
}
}
}
regexes are nicer though... they make your code look a lot a tider and readable. although if you don't have a library for them it will be faster to just implement it like this... :)
If you are using Windows, you can use win32 api function https://learn.microsoft.com/en-us/windows/win32/api/icmpapi/nf-icmpapi-icmpsendecho2.