How can I find the InternetRegistry User Key or Parent Registry Key - c++

I have a BHO which on the first run is gathering activation information and storing this in the registry.
(I think) due to IE's permission's I am only able to store this in the registry branch
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\InternetRegistry\REGISTRY\USER\S-0-0-00-000000000-000000000-000000000-0000\Software\MyBHO\MyKey
Where S-0-0-00-000000000-000000000-000000000-0000 is a unique key for each user.
Which is fine using RegCreateKey() with "Software\MyBHO\MyKey". It's all created and running lovely. It determines where in space to store the Key with no problems.
The Problem:
When I carry out an uninstall I want to remove this key and as this is run outside of IE I have no way to determine where that key is / what the user string is.
Options I have in mind:
Option 1 (Ideal)
Find out this user string first to then build a new path for the key I wish to remove and remove it. How?
Option 2
At the point of activation store the path to the key in another registry value that can be accessed. Then read, and delete both (Which seems a bit backwards and probably wont work due to the access restrictions of the BHO on the registry (Thus it being written there in the first place))
Do you know if there is any way to find this User key or even how to find the parent dir.
Edit Upon continued research I've found that the thing I'm referring to as "user key" is the current Users "SID". Maybe this will yield me better results.

Call GetUserName to get the user name, and LookupAccountName to get his SID.
ConvertSidToStringSid is a useful utility function to format a SID as a S-1-5-32-00000000-00000000-00000000-00000000-0000 string

If you really want to write per-user data to the registry, use IEGetWriteableHKCU().
In general there is no good way to remove per-user data at uninstall. For example, what if you install as user A and the uninstall as user B? Are you going to go find all of them and delete them? Just leave the turds behind.
Alternatively you could consider using a different data store. Do you really need the registry? Can you store this data in a file? What about Web Storage?

Related

Login - pass user data to new windows / store it as static information? [Desktop App]

I'm trying to make a desktop C++ application (using Qt, if it matters for this problem) that features an authentication system. It can be used by ONE user at a time. When the application starts, a log in form will allow the user to type his username and password. After logging in, a new window will be displayed. My question is: should I pass the user's ID and/or username to the next window [as a constructor parameter?] (and use such system for other windows as well) OR would it be ok (I'd much rather prefer this) to store this data in the static fields of a class and access it from everywhere? [doesn't sound too bad since I only allow ONE user to be logged in at any time]. I should also mention that I'll be trying to use the Model-View-Controller pattern.
Do you need to store it? I mean, once user clicks "Login" on your login dialog, it checks whether entered name/password combination is authorized to use the app and than the rest of the app starts, knowing user is authorized and without any other checks/using of credentials.
In case you do need to store username (for example you display somewhere in header that user is logged in as XXX or you use it for some other reason) I would recommend to save it statically somewhere. The other way (passing it all over the place) means that you would have to store copies userID/name all over the rest of your app.
Also, if you have more user-releated information (like selected theme, some configs, user specific file paths or something) keep it in one place (create struct/object with all this in it)
Pro tip #1:
Do not store password in that struct. Once you check whether user is authorized or not dump it. And by that I mean don't just stop using it/forget pointer but overwrite all places in memory where the password was stored to prevent some RAM reading attacks.
// Example
char *password = getPasswordFromLoginDialog();
// Do some stuff (check it)
while (*password) { // while we are not at the end of 0 terminated string
*password = 0; // zero it
password ++; // move on
}
Pro tip #2:
Usual way to compare 2 strings is to go char by char and once they are not the same tell that 2 strings differ and thus password is not accepted. However, it takes marginally longer time to find char missmatch at say 7th position than at 1st. Attacker can exploit that using brute-force and statistics and work out password one char by one.
Easy way to defeat this: After user tries to login wait random period of time and after that start checking if the password is correct or not. This way it will disrupt this time based brute-force attack
More proper way how to check whether password is correct or not: Don't check actual password, but hash it first using some crypto-secure hash like SHA256 and then compare hashes. Preferably hash the hash and hash the hash of hash and so on, about 1000 times, so it takes much longer to bruteforce if attacker gets raw hash of password.
Pro tip #3:
Never ever hardcode usernames/passwords into your application. It is pretty easy to decompile and pull these pairs from it. I don't know exactly what you are working on, but I would suggest querying 1000 times hashed hashes of password from some SQL database or something like that. If you have to use hardcoded passwords, dont use raw string, but those hashes
Pro tip #4:
Use salt (Salt - wiki). That is pretty much some random data you put before/after password before you hash it. For additional security it is better to assign each user different salt.
Reason for salts is that same passwords have same hashes. When you have lookup table of common passwords and hashes, you can de-hash password very easily. Not using different salt for each user (or not using it at all) has some consequences: when there is a leak of password(hashes) database attacker instantly knows which users have same password
Pro tip #5:
If you are using some sort of client-server authorization system, make sure you salt-hash password client side (before sending it over network) and also on server side (before storing to db/comparing against db). This way when there is a leak of db attacker can't use those stored hashes to authorize himself, because they get hashed (once) more on server side before actual authorization process.
Keep in mind, that if attacker intercepts salt-hashed password when client is sending it to server he CAN use it to authorize himself. However, when using network, you should encapsulate all your traffic in some sort of encrypted tunnel (have a look at TLS)
Hope this helps

Mediawiki mass user delete/merge/block

I have 500 or so spambots and about 5 actual registered users on my wiki. I have used nuke to delete their pages but they just keep reposting. I have spambot registration under control using reCaptcha. Now, I just need a way to delete/block/merge about 500 users at once.
You could just delete the accounts from the user table manually, or at least disable their authentication info with a query such as:
UPDATE /*_*/user SET
user_password = '',
user_newpassword = '',
user_email = '',
user_token = ''
WHERE
/* condition to select the users you want to nuke */
(Replace /*_*/ with your $wgDBprefix, if any. Oh, and do make a backup first.)
Wiping out the user_password and user_newpassword fields prevents the user from logging in. Also wiping out user_email prevents them from requesting a new password via email, and wiping out user_token drops any active sessions they may have.
Update: Since I first posted this, I've had further experience of cleaning up large numbers of spam users and content from a MediaWiki installation. I've documented the method I used (which basically involves first deleting the users from the database, then wiping out up all the now-orphaned revisions, and finally running rebuildall.php to fix the link tables) in this answer on Webmasters Stack Exchange.
Alternatively, you might also find Extension:RegexBlock useful:
"RegexBlock is an extension that adds special page with the interface for blocking, viewing and unblocking user names and IP addresses using regular expressions."
There are risks involved in applying the solution in the accepted answer. The approach may damage your database! It incompletely removes users, doing nothing to preserve referential integrity, and will almost certainly cause display errors.
Here a much better solution is presented (a prerequisite is that you have installed the User merge extension):
I have a little awkward way to accomplish the bulk merge through a
work-around. Hope someone would find it useful! (Must have a little
string concatenation skills in spreadsheets; or one may use a python
or similar script; or use a text editor with bulk replacement
features)
Prepare a list of all SPAMuserIDs, store them in a spreadsheet or textfile. The list may be
prepared from the user creation logs. If you do have the
dB access, the Wiki_user table can be imported into a local list.
The post method used for submitting the Merge & Delete User form (by clicking the button) should be converted to a get method. This
will get us a long URL. See the second comment (by Matthew Simoneau)
dated 13/Jan/2009) at
http://www.mathworks.com/matlabcentral/newsreader/view_thread/242300
for the method.
The resulting URL string should be something like below:
http: //(Your Wiki domain)/Special:UserMerge?olduser=(OldUserNameHere)&newuser=(NewUserNameHere)&deleteuser=1&token=0d30d8b4033a9a523b9574ccf73abad8%2B\
Now, divide this URL into four sections:
A: http: //(Your Wiki domain)/Special:UserMerge?olduser=
B: (OldUserNameHere)
C: &newuser=(NewUserNameHere)&deleteuser=1
D: &token=0d30d8b4033a9a523b9574ccf73abad8%2B\
Now using a text editor or spreadsheet, prefix each spam userIDs with part A and Suffix each with Part C and D. Part C will include the
NewUser(which is a specially created single dummy userID). The Part D,
the Token string is a session-dependent token that will be changed per
user per session. So you will need to get a new token every time a new
session/batch of work is required.
With the above step, you should get a long list of URLs, each good to do a Merge&Delete operation for one user. We can now create a
simple HTML file, view it and use a batch downloader like DownThemAll
in Firefox.
Add two more pieces " Linktext" to each line at
beginning and end. Also add at top and at
bottom and save the file as (for eg:) userlist.html
Open the file in Firefox, use DownThemAll add-on and download all the files! Effectively, you are visiting the Merge&Delete page for
each user and clicking the button!
Although this might look a lengthy and tricky job at first, once you
follow this method, you can remove tens of thousands of users without
much manual efforts.
You can verify if the operation is going well by opening some of the
downloaded html files (or by looking through the recent changes in
another window).
One advantage is that it does not directly edit the
MySQL pages. Nor does it require direct database access.
I did a bit of rewriting to the quoted text, since the original text contains some flaws.

Checking File Permission on Windows for non elevated users

I am writing some C++ code for the Windows(XP/7) platform to check the permission associated to a file. I want to verify that the file I am reading cannot be written by accounts with non elevated privileges. This is what I am currently doing:
I get the DACL associated with the file calling GetNamedSecurityInfo
I call CreateWellKnownSid with well known Sids, such as WinAuthenticatedUserSid (the Users group)
I call BuildTrusteeWithSid to build a TRUSTEE with the previous SID
I call GetEffectiveRightsFromAcl with the previously created trustee to get the effective acl
I check that the ACL does not contain the Write Flag set.
This code is working perfectly for the Users group. What about the other groups such as Everyone, Guests, or other specific users which may have specific write access on the file? I would like to find a solution where I don't need to enumerate all possible SID and check against all of them. Is there a SID I could use such as "anything but not admin"?
Regards,
Ant
I'd take a slightly different approach:
Get all ACE's via GetExplicitEntriesFromAcl, for the file and all its parents
Select the GRANT_ACCESS and SET_ACCESS ACE's
Get the list of trustees from the selected ACE's
For each of the trustees, perform an access check. GetEffectiveRightsFromAcl is probably the easiest solution here.
You'll want to think specifically what you want to do with the OWNER. He can alter the rights at any time.

Saving passwords inside an application

I am writing an application that needs to read a user name and password and store them so that the program can read them again later. Storing it in some variables sounds like a stupid idea.
Found that KDE library, but it has too huge dependency, and I am too newbie programmer to understand how to use it.
What are the common Methods to storing passwords, and how I can solve my problem?
It depends on what you are going to do with the information.
If you are going to use the name and password to access some external service (but the user will have to reenter the information the next time the program is run), then storing them in some variables is OK. It might be wise to store them encrypted (at least, store the password encrypted) so that it is not visible in core dumps or the equivalent. When the password is needed, you decrypt it, use it, and then write over where the decrypted version was stored (zapping it). (Note: hashing is not appropriate in this context; you need to be able to see the password, and you can't undo a hash.) You could decide to store the information outside the program (in a disk file), but it doesn't seem necessary. Note that the binary will still contain the encryption key (and encryption algorithm), and encrypted data is more random than the average contents of your program, so to really conceal the encrypted password is actually very difficult (verging on impossible). However, you can make it hard enough that it will stop all but the most determined attackers.
If you are going to store the username and password as a permanent record so that you can validate that the same user is accessing the information in the future, then you must use storage external to the program; you will use a simple database, which might be as simple as a plain text file if you ensure you resolve any concurrency issues. In this case, you will hash the password with some salt, and you'll store the username, salt and hashed password in such a way that given the username, you can easily find the other two values.
Night Walker comments:
I use that password to access some web database, so I need it stored in my application after it is entered for the first time. Are you sure a plain text file is that smart an idea?
It depends on how you conceive 'stored in my application'. You can't modify the executable, or at least shouldn't try to do so. So, you need to look on it as a permanent record stored in some sort of file separate from the application executable. On the other hand, you do face a different problem from what I outlined - you are not authenticating the user with the information; you need to decrypt the information on demand to send on to other applications.
First off, that means that salts and hashes are not relevant; you need to reverse the masking operation, and you can't reverse a hash.
Next, you need to decide how you will identify the user of your application upon reappearance. Will the user be obliged to enter some password to get to their own data, or will you simply rely on the operating system privileges, or some other scheme.
If the user must enter some password into your application to get going, then you can consider using that password (or a hash of it, distinct from the password hash used to recognize the password to the application) to encrypt the username/password combination for the external application. You can then store the username and, for sake of argument, a Base-64 encoded version of the encrypted password into a text file; this is as safe as the application password, which is stored in the original salted hash format. When the user returns, they have to supply their application username and password, and you can validate that combination against the stored values, and then use the password to decrypt the password to the external application.
If the user does not enter a password, then you are more restricted in what you can do. You have to be able to determine a key somehow from the information available to you that can be used to store the user's encrypted password in a file in a restricted location such as a sub-directory underneath their home directory with no group or public access:
mkdir ~/.appname
chmod 700 ~/.appname
cp /dev/null ~/.appname/app.key
...store the encrypted information...
chmod 500 ~/.appname
chmod 400 ~/.appname/app.key
This is less satisfactory because even if you combine a fixed key with the user's name, say, the chances are that someone can work out what that key is (and the encryption technology) and reverse engineer it. (The secrecy of encrypted data depends on the keys; when the key is determinable by the program, it is also determinable by a determined attacker. It is best, by far, to rely on the user to provide the key (or a password or pass phrase) at run-time; then the application does not store anything that an attacker can use offline.
Usually you store the username and a hashed version of the password. See this wikipedia article: hash functions, and this question.
Common method to store passwords for later use is to store them in some encrypted cache. That cache is encrypted using some master password. User should enter master password each time you need password from cache. KeePassX is a small open source application that uses master password to store personal data (user names, passwords, etc.) It has a light interface, is cross platform and published under the terms of the GNU General Public License. You could check it as sample and use some parts of it.
What about MySQL or SQLite? Hash the password and store them in a persistent database, no?
I would suggest storing a hashed password in SQLite. Then whenever you need to check a password, hash it and then compare it against the stored value. This keeps the stored passwords secure so no one (not even you) know what they are.
what kind of application is it? There are many methods but if its ASP.Net it's common to encrypt in the web.config file.
At spotep.com we only store the username and a hashcode of the username combined with the password. The benefit of this is that similair (often trivial) passwords wont result in the same hashcode (which is stored in a cookie, and therefore very unsafe).
You could try QSettings which provides persistent platform-independent application settings. Solutions like mysql would be overkill unless you have hundreds of passwords to store.

Registry hive question

Does anyone have a smal example of how to programmatically, in c/c++, load a users registry hive? I would loike to load a hive set some values and close the hive.
Thanks in advance for any help.
Tony
You can use RegLoadKey() and RegUnLoadKey(). You can build the paths to the user hives (NTUSER.DAT) via the HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList. However, it's generally not a good idea to use these functions willy-nilly. If the user tries to logon while you have his profile loaded, he will be unable to load his profile and will get a temporary default profile.
Documentation says you should pass predefined key HKEY_CURRENT_USER as first argument of RegOpenKeyEx function.
You can also enumerate HKEY_CURRENT_USER passing it directly to RegQueryInfoKey.
I haven't got a specific example, but the Windows API calls you need would be:
RegOpenKeyEx() to load the registry
key
RegSetValueEx() / RegGetValue() [and sister
functions] to get/set registry values
RegCloseKey() to close the
registry.
There's some example code behind this link on codersource.net ... although I can't vouch for how complete or correct it is. Review against the MSDN :-)