Why does the golden ticket work without any user password hash? - active-directory

In step five in Kerberos Authentication, The user sends the TGS ticket and data that encrypted with new session key received from the KDC in step 4 to the service he wants to connect to. But in Golden Ticket Attack, The user create own fake tgt with krbtgt account password ntlm hash and sends it to KDC directly. then the attack succeeds. In step 5, the user needs to know the session key received from KDC in step 4 to able to send TGS. But the session key is encrypted with user account password. Why the golden ticket attack is succeed without user account hash with only krbtgt account hash?
I'm waiting for a logical reason why the golden ticket works

The session key that's encrypted with the user's key is not actually part of the ticket; it's delivered as a separate field in AS-REP (and stored separately in the ticket cache as well).
What the ticket contains is a second copy of the session key that's encrypted using the service's key instead of the user's (that's how it gets delivered to the service in the first place). See diagram.
(Note that a KDC is stateless and does not remember the "session" between AS-REP and TGS-REQ. The ticket-granting service behaves like any other kerberized service; it doesn't learn the session key directly from the KDC, but has to receive it encrypted within the ticket.)
So if you know the key for 'krbtgt', you can use it to decrypt the entire 'krbtgt' ticket including the session key that the KDC would receive – you don't need the copy that's meant for the user at all.
Actually, if you're crafting a fake krbtgt ticket, then you're the one who has to generate and encrypt this session key in the first place, so you already know the unencrypted version anyway.

Related

Is it safe store a username inside a cookie?

I working on security and I 'm storing a session key inside a cookie. I will use it to check if the user is actually connected and if he didn't tried to change some info.
at first I think to just check if the session key is inside the database, but I think it would be more secured to check if the current user has the session key instead of just finding a user that have that key and assume that he must be the one connected.
I know I should use session storage, but since I'm using AngularJS, I don't know how to achieve that, so no need to point out that I should use session instead.
-Would it be safe to put the username inside the cookie?
-Would just using the session key and assume that the user that got the key most be the connected one be a good idea (it would simplify some of my request to the database later on)?
It sounds like essentially what you are trying to achieve by storing the username in a cookie is to make the username a 2nd factor in a 2-factor authentication scheme. The problem is, the username always travels in a cookie alongside the session id and so when one is exposed, the other is too. So no security is gained.
Furthermore, there is no valid security argument to storing username in a client cookie and then trusting that this username is the same one associated with a session. The client can trivially change the value of the cookie before submitting a request. And any attacker that has already managed to have sniffed out the session id from a cookie could probably just have easily read the username cookie too, making a session hijack attack practically the same difficulty. At best, you've achieved no higher security and added unnecessary complexity to your code. At worst, you've betrayed usernames which wouldn't have otherwise have been visible to an attacker. eg. in the case of expired sessions.
OWASP Recommendation:
Session ID Content (or Value)
The session ID content (or value) must be meaningless to prevent information disclosure attacks, where an attacker is able to decode the contents of the ID and extract details of the user, the session, or the inner workings of the web application.
The session ID must simply be an identifier on the client side, and its value must never include sensitive information (or PII). The meaning and business or application logic associated to the session ID must be stored on the server side, and specifically, in session objects or in a session management database or repository. The stored information can include the client IP address, User-Agent, e-mail, username, user ID, role, privilege level, access rights, language preferences, account ID, current state, last login, session timeouts, and other internal session details. If the session objects and properties contain sensitive information, such as credit card numbers, it is required to duly encrypt and protect the session management repository.
It is recommended to create cryptographically strong session IDs through the usage of cryptographic hash functions such as SHA1 (160 bits).
-- https://www.owasp.org/index.php/Session_Management_Cheat_Sheet#Session_ID_Content_.28or_Value.29

Right way to store which user is connected in my AngularJS app

I'm trying to keep in my app which user is connected. I'm really not sure if I'm doing this correctly. So here is how I plane to do it:
First I use my Slim API to check if the username and password are correct and if has access privilege.
If it returned the username and his privilege level, I will store them in a cookie and use those two information in the app.
The problem is that I'm afraid that if I store the username in a cookie, someone could try to change the cookie and put an other username instead.
Is it alright to only use the username for my requests to the DB as soon as the user is connected (like get all item of a user using the name of the user), or should I use a more secured and efficient way, if there is one?
P.S: I'm not asking how to have my site remember the user when he go back to the site. I'm asking how I should remember the username and other information while my user is still on my site in a secured way.
You should generate a long random number password and store that in a cookie. This random number is essentially just another unique password for this user. So, on the server side, you only store a properly salted hash of this random number. Think of this like a Hash key for that user stored in DB, and you use this HASH key to decrypt the long ramdom password.
You could encrypt these informations in the cookie, so nobody can steal these ones. Each time a user is trying to launch your application check if the credentials in the cookie are still correct (Is this username in your databse ? Is the accreditation level correct for this user ?). So you know if these informations have been changed. If they aren't correct you invite the user to login again.

Do I need to encrypt secret access key?

I'm creating a mobile REST API.
Currently, when user signs in with email and password, I generate secret session key (64 chars long), store it in database and send it to the user so that user doesn't need to log in again for the future request until they logged out.
For the next requests, I just check if the provided session key is equal to the one in database.
But, there is a big security loophole I see in this scheme. If the attacker got access to the database, they can use the secret key and impersonate anyone without knowing the password at all. What's the point of encrypting the password in this case besides obscuring user's real password - it doesn't prevent anything else.
So, my question is how do you store these access key correctly?
Twitter will send session key on sign in on their API. So, how do they store these keys?
Thanks.
It's even better to hash the session key, just as if it was a password, and store the hashed value in the database.
The only difference from password hashing is that, since your session keys are (I hope, at least) generated by a secure random number generator and long enough to be unguessable by brute force (I'd recommend at least 128 bits of randomness), you:
don't need a separate salt, and
can use a simple cryptographic hash function like SHA-256 instead of a deliberately slow password hashing scheme like PBKDF2.
Not using a salt also allows you to use the (hashed) session key to look up session records in the database, so you don't need a separate session ID for that.
So, to sum it up:
When starting a new session, generate the session key using a secure RNG, store the SHA-256 hash of the session key in your database, and send the (unhashed) session key to the client.
When the client makes a request, hash the session key sent by the client using SHA-256, and look up the corresponding record in the database.
You may also wish to limit the lifetime of session keys, and to provide some mechanism for the client to explicitly invalidate all of the user's sessions, to mitigate the effects of a compromise of individual session keys.

should I hash username in OTP based two factor authentication database?

I currently dealing with a ssh two factor authentication plugin.
It can be used like this:
$ ssh localhost
password: [ssh password]
Name: [your name]
OTPCode: [your code]
there is a list of username and OTP Secret in sqlite db.
if the sqlite db leaks, it is dangerous. should I hash the username and add a nick name to distinguish a which one is which. will this design cause any problem or is it neccesary?
To be honest, if someone gets hold of the database in the clear with the secrets in it, they aren't going to be too bothered about hashed/obfuscated usernames. They already have the secret information.
An attacker could realistic generate all the OTPs against all the secrets from the database in a fraction of a second and then try them all for any given username. Moreover if they have sniffed the username in the past and know when they authenticated (For TOTP), they can create all the OTPs for all the secrets in the database for that window and then see which secret corresponds to that user.
Basically if you loose your token's shared secret, loosing the corresponding username is going to be the least of your worries.
Focus on locking down the database or even better getting the authentication mechanism off of the machine.

How to securely store a password in a database while still being recoverable

For an application that I am working on I want to store passwords that a user enters in a way that provides some security in the event that my database is compromised but still allows an external daemon to have access to the plaintext version of the password. (It will be used for IMAP or POP logins).
What is the best way to store a password in the database so it is recoverable without the user's original password. (Not encrypted with the user's password)
I was thinking maybe public key encryption where the front end would use the public key to encrypt the password for store in the database and then the accessing daemon would decrypt the password with the private key.
EDIT:
I need the plaintext passwords so that they can be used to log on to other websevices which may not support something like OAuth
You should encrypt them, preferably with asymmetric encryption. Ideally the application (web app) encrypts them (w public key), and the daemon decrypts them (w private key), and the application and daemon and db live on different machines in different network zones.
Ideally the private key lives in a hardware security module attached to the daemon server. YubiHSM is ~ $500.
Please note that this only applies to passwords that you need to send to another party. If the password is for authenticating users with your system, then they should be hashed (and salted, and peppered).

Resources