Can't find any flowcharts on how communication works between peers. I know how it works in Radius with PAP enabled, but it appears that with MS-Chapv2 there's a whole lot of work to be developed.
I'm trying to develop a RADIUS server to receive and authenticate user requests. Please help me in the form of Information not code.
MSCHAPv2 is pretty complicated and is typically performed within another EAP method such as EAP-TLS, EAP-TTLS or PEAP. These outer methods encrypt the MSCHAPv2 exchange using TLS. The figure below for example, shows a PEAP flowchart where a client or supplicant establishes a TLS tunnel with the RADIUS server (the Authentication Server) and performs the MSCHAPv2 exchange.
The MSCHAPv2 exchange itself can be summarized as follows:
The AS starts by generating a 16-byte random server challenge and sends it to the Supplicant.
The Supplicant also generates a random 16-byte peer challenge. Then the challenge response is calculated based on the user's password. This challenge response is transmitted back to the AS, along with the peer challenge.
The AS checks the challenge response.
The AS calculates a peer challenge response based on the password and peer challenge.
The Supplicant checks the peer challenge response, completing the MSCHAPv2 authentication.
If you'd like to learn about the details and precise calculations involved, feel free to check out my thesis here. Sections 4.5.4 and 4.5.3 should contain all information you need in order to implement a RADIUS server capable of performing an MSCHAP exchange.
As you can see in the figure, many different keys are derived and used. This document provides a very untuitive insight into their functionality. However, the CSK is not explained in this document. This key is optionally used for "cryptobinding", i.e. in order to prove to the AS that both the TLS tunnel and MSCHAPv2 exchange were performed by the same peer. It is possible to derive the MSK from only the TLS master secret, but then you will be vulnerable to a relay attack (the thesis also contains a research paper which gives an example of such an attack).
Finally, the asleap readme gives another good and general step by step description of the MSCHAPv2 protocol, which might help you further.
Unfortunately i can't add anymore comments, the demand is for me to have 50 reputation.
To your request:
My lab enviorment is of SSL-VPN used with AS of RADIUS.
Constructed with the following 3 items:
End-User -> there's no 'client' installed, the connection starts through a web portal. client = web browser
NAS -> This is the machine that provides the web-portal(the place the End-User enters the Username & Password) AND acts as a RADIUS CLient, transfering requests to the AS.
AS(RADIUS) -> This is me. I receive the access-requests and validate the username & password.
So in accordance with that, what i receive in the Access-Request is:
MS-CHAP2-Response:
7d00995134e04768014856243ebad1136e3f00000000000000005a7d2e6888dd31963e220fa0b700b71e07644437bd9c9e09
MS-CHAP-Challenge: 838577fcbd20e293d7b06029f8b1cd0b
According to RFC2548:
MS-CHAP-Challenge This Attribute contains the challenge sent by a NAS to a Microsoft Challenge-Handshake Authentication Protocol (MS-CHAP) user. It MAY be used in both Access-Request and Access-Challenge packets.
MS-CHAP2-Response This Attribute contains the response value provided by an MS-
CHAP-V2 peer in response to the challenge. It is only used in
Access-Request packets.
If i understand correctly, and please be calm this is all very new to me, based on your flowchart the AS is also the Authenticator who inits the LCP.
And in my case, the LCP is initiated by the NAS, So my life made simple and i only get the Access-Request without needing to create the tunnel.
My question now is, how do i decrypt the password? I understood there's a random challenge 16-byte key but that is held by the NAS.
From my recollection, i only need to know the shared secret and decrypt the whole thing using the algorithem described in your thesis.
But the algorithem is huge, i've tried different sites to see which part of it the AS supposed to use and failed in each attempt to decrypt.
Since i can't ask for help anymore in this thread, i can only say this little textbox cannot fill the amount of gratitude i have for your help, truely lucky to have you see my thread.
Do email me, my contact info are in my profile.
Also, for some reason i can't mark your answer as a solution.
"is typically performed within another EAP method such as EAP-TLS, EAP-TTLS or PEAP."
Well...
RADIUS win2008 server here, configured to NO EAP, only MS-CHAPv2 encryption, to replace the PAP.
This is why alot of what you said and what i said wasn't adding up...
I'm not MITM, i'm the AS, and my NAS(the one who knocks) is the RADIUS_Client/Authenticator.
When the user enters UN&PW a random encryption, which i'm now on the look for, is created with MS-CHAPv2 and all of the above is irrelevant.
With the items received from the Authenticator which again are:
- Username, MS-CHAP-Challenge, MS-CHAP2-Response
The AS performs a magical ceremony to come up with the following:
-Access-Accept
-MPPE-Send-Key
-MPPE-Recv-Key
-MS-CHAP2-Sucess
-MS-CHAP-DOMAIN
This is from a working scenario, where i have a RADIUS server, a radius client and a user.
A NOT working scenario, is the one where i am the RADIUS Server(AS), cause that's my goal, building a RADIUS server, not MITM.
So all i got left is finding out what decryption algorithem needed for those and how.
Related
I don't think this is possible, but I'll ask anyway. Here is what I am trying to do:
I have a HTML5 game that users play in their browser. When the game is over, they see their final score. I want to be able to send that score in an encrypted format to the server. I don't want the players to be able to reverse engineer the server call and set their score higher than what they actually earned. Is there a way to encrypt this and make it impossible for the player to reverse engineer it?
Short Answer: No, what you want to achieve cannot be done, but not for the reasons you think.
Long Answer: You can most certainly encrypt the final score and send it to your server. You can even do this in a way that means that the user couldn't hope to decrypt it once encrypted.
The flaw lies in the fact that the user can encrypt whatever they like in the first place. Let's say you send the encrypted score to the server in an HTTP POST request at the end of the game. Nothing stops the user from taking apart your JS, finding the public encryption key and submitting that same POST request without ever actually playing your game.
To actually solve your problem: The game must be controlled on the server. The client side of the game must simply send input actions which are then interpreted on the server. Since the gamestate is only ever modified by the server, no fake scores can be generated.
On the client device, a synced Realm can be setup with an encryption key that's unique to the user and stored on the device keychain, so data is stored encrypted on the client.
(related question: Can "data at rest" in the Realm Mobile Platform be encrypted?)
Realm Object Server and the clients can communicate via TLS, so data is encrypted in transit.
But the Realm Object Server does not appear to store data using encryption, since an admin user is able to access all the database contents via Realm Browser (https://realm.io/docs/realm-object-server/#data-browser).
Is it possible to setup Realm Mobile Platform so user data is encrypted end-to-end, such as no one but the user (not even server admins) have access to the decryption key?
Due to the way we handle conflict resolution, we currently are unable to provide end-to-end encryption, as you correctly deduced. Let's go a tiny bit into detail with regards to the conflict resolution.
In order to handle conflicts the way we do, we use something called operational transformation. This means that instead of sending the data over directly, the client tells the server the intent of the change, rather than the result. For example, when two users edit a text field, we would tell the server insert(data='new text', offset=0) because the first user prepended data at the beginning of the text field, and insert(data='some more stuff', offset=10) because the second user added data in the middle of the field. These two separate operations allow the server to uniquely resolve what happened, and have conflictless resolution of the two writes.
This also means that if we encrypt everything, the server would be unable to handle this conflict resolution.
This being said, that's for the current version. We do have a number of thoughts on how we could handle this in the future, while providing (some degree) of encryption. Mainly this would mean more work on the client, and maybe find a new algorithm that would allow us to tell the client the intent, and let the client figure out how to merge everything. This is a quadratic problem, though, so we're reticent to putting too much work on the client side, as it could really drain the battery.
That might be acceptable for some users, which is why we're looking into it. Basically, there will be a trade-off. As the old adage goes: fast, secure, convenient: pick two. We just have to figure out how to handle this properly.
I just opened a feature request around possibly using Tresorit's ZeroKit to solve the end-to-end encryption question posed. Sounds like the conflict resolution implementation will still cause an issue though, but maybe there is a different conflict resolution level that can be applied for those that don't need the realtime dynamic editing of individual data fields (like patient health data, where only a single clinician ever really edits a record at any given time).
https://github.com/realm/realm-mobile-platform/issues/96
I'm very much fascinated by RSA SecurID and similar 2-factor systems.
I have been through many articles including this one: https://security.stackexchange.com/questions/9584/can-the-numbers-on-rsa-securid-tokens-be-predicted
My question is, since RSA's algorithm uses a "seed" and the numbers therefore generated are in a "series".
What if I generated a token on the secure device when the server asked for it and instead of using that token I pressed the button again to generate another token?
Would this not cause a "mismatch" in the series running on the device and on the server?
It would have been easier if the logic just depended on the clock and device serial or so but since there are seed and random numbers involved, I wonder what happens if you skip a token or two?
Thanks.
As I understand it, the SecurID tokens don't use a "rolling counter" — the token is generated solely from the device serial and the current time. Also: in the RSA SecurID tokens I've seen (admittedly limited), the user doesn't press a button to generate the token; instead the token is constantly visible on the screen. Thus the token generated doesn't get out of sync (in the sequence) with the server, except for the possibility of clock drift on the token side (usually servers use NTP and so their clock drift is negligible).
However, the typical solution for clock drift problems is to store a "drift" parameter on the server, on a per-token basis. This drift parameter can be updated manually (for maximal security but also maximal pain) or one can check the surrounding intervals on the server side. For example, if I log in now, you might check the server's current sixty-second interval, the previous one, and the next one all for validity, and if the previous/next are valid, you store that drift for the token.
On the other hand, there is an algorithm that suffers from the problem you've described: the HMAC-based One-time Password Algorithm. It uses a rolling counter that is supposed to be synchronized on both the server and the token. So, if you have a HOTP-based authenticator and you press the token generate button many times, you will cause it to fall out of sync, and manual intervention is required by the server administrator.
A similar solution can be enacted as above: check the next few values of the counter, say counter+1, counter+2, counter+3, etc., and store that as a 'drift' parameter. Depending on how far out one checks, the token could eventually go out of sync, if it were pressed repeatedly.
A variant of HOTP that fixes is the problem is the time-baesd version, which uses a "time counter" instead of a real counter. This is what Google Authenticator uses. Here, you still have the clock drift problem, with the same solution as above.
If you are fascinated by the OTP systems then you should read RFC 4226 which describes HMAC-Based OTP algorithm and RFC 6238 which describes TIME-Based OTP algorithm as these two algorithms are used by the most of the OTP solutions available today.
If you are interested also in the recent developments in the area of two factor authentication then you should visit website of FIDO Alliance and take a look at their specs too.
In an app, I Have a network server and clients.
After a handshake, let's say the client sends "userId sessionId SOME_COMMAND param param param".
I have already identified the client and the sessionId is checked on the server accordingly, so identity is no more an issue.
But I'd like to prevent a hacker to modify the message or create a false one, for example sending "userId sessionId SOME_COMMAND paramModified paramModified paramModified".
I thought about using a pair of private/public encryption keys, and send the hash of the message in the message itself. But since it's automated in the client program, I may have to send the public key during the handshake. So the hacker could simply retrieve it and generate the proper hash.
I could also use complex encryption seeds or algorithms, but my experience with hackers has shown me that they will decompile anything.
So the bottom line is: I can hide everything that runs on the server, but I can't hide anything on the client program. And I'd like to to forbid to modify the message that the client program is supposed to send.
I don't even know if it's possible. And I'm opened to any suggestion. And by the way, I'm using Java, although it should not be very relevant. Thanks.
Forget it. Use SSL like everybody else. There are complexities which you haven't even begun to address.
Recently, I've been reading up on the IRC protocol (RFCs 1459, 2810-2813), and I was thinking of implementing my own server.
I'm not necessarily looking into adhering religiously to the IRC protocol (I'm doing this for fun, after all), but one of the things I do like about it is that a network can consist of multiple servers transparently.
There are a number of things I don't like about the protocol or the IRC specification. The first is that nicknames aren't owned. While services like NickServ exist, they're not part of the official protocol. On the other hand, implementing something like NickServ properly kind of defeats the purpose of distribution (i.e. there'd be one place where NickServ is running, and one data store for it).
I was hoping there'd be a way to manage nicknames on a per-server basis. The problem with this is that if you have two servers that have some registered nicknames, and they then link up, you can have collisions.
Is there a way to avoid this, without using one central data store? That is: is it possible to keep the servers loosely connected (such that they each exist as an independent entity, but can also connect to one another) and maintain uniqueness amongst nicknames?
I realize this question is vague, but I can't think of a better way of wording it. I'm looking more for suggestions than I am for actual yes/no answers. So if anyone has any ideas as to how to accomplish nickname uniqueness in a network while still maintaining server independence, I'd be interested in hearing it. Note that adhering strictly to the IRC protocol isn't at all necessary; I've got no problem changing things to suit my purposes. :)
There's a simple solution if you don't care about strictly implementing an IRC server, but rather implementing a distributed message system that's like IRC, but not exactly IRC.
The simple solution is to use nicknames in the form "nick#host", much like email. So instead of merely being "mipadi", my nickname could be "mipadi#free-memorys-server.net". So I register with just your server, but when your server links up with others to form another a big ole' chat network, you can easily union all the usernames together. There might be a "mipadi" on otherserver.net, but then our nicknames become "mipadi#free-memorys-server.net" and "mipadi#otherserver.net", and everything is cool.
Of course, this deviates a good deal from IRC. :)
They have to be aware of each other. If not, you cannot prevent the sharing of nicknames. If they are, you simply need to transfer updates on the back-end. To prevent simultaneous registrations, you need a transaction system that blocks, requests permission from all other servers, and responds.
To prevent simultaneous registrations during outages, you have no choice but to timestamp the registration, and remove all but the last (or a random for truly simultaneous) registered copy of the nick.
It's not very pretty considering these servers aren't initially merged in the first place.
You could still implement nick ownership without a central instance, if your server instances trust each other.
When a user registers a nick, it is registered with the current server he's connected with
When a server receives a registration that it didn't know of, it forwards that information to all other servers that don't know it yet (might need a smart algorithm to avoid spamming the network)
When a server re-connects to another server then it tries to synchronize the list of registered nicks and which server handles which nick
If there is a collision during that sync, then the older registration is used, and the newer one marked as invalid
If you can't trust your servers, then it'll get a lot harder, as a servers could easily claim every username and even claim the oldest registration for each one.
Since you are trying to come up with something new, the idea that springs to mind, is simply including something unique about the server as part of the nick name when communicating outside of the server. So if you want to message a user on a different server you might have something like user#server
If you don't need them to be completely separate you might want to consider creating some kind of multiple-master replicated database of accounts. Where each server stores a complete copy of the account database, and each server can create new accounts which will be replicated to other servers as possible. You'll probably still have to deal with collisions on occasion though.
While services like NickServ exist, they're not part of the official protocol.
Services are not part of the official protocol because they've nothing to do with the protocol. They're bots with permissions. There's no reason why you couldn't have one running on each server but it does make them harder to maintain.
If you were to go down that path, I would probably suggest the commonly used "multiple master" database replication technique. If one receives a write (in your case, a new user is created or updated, etc) it sends the data to all the other nodes. You'll have to be careful though. If one node is offline when the others get an update, it will need to know to resync on reconnection.
Another technique would be as above but in reverse. Data is only exchanged between nodes when it's needed. Eg if a user tries to log in on a node where there's no data for it, it'll query the others and issue a move order to get all the data to that one node. This is potentially less painful than the replication version but there could be severe problems in netsplits if somebody signs up on a node disconnected from the pack for a duplicate nick.
One technique to nullify the problems of netsplits would be to make chat nodes and their bots netsplit-aware. When they're split, they probably shouldn't allow any write actions... But this could impact on your network if you're splitting lots.
You've also got to ask how secure this might or might not be. IRC network nodes are distributed for performance but they're not "secure". Because of this, service bots are usually run centrally to keep ultimate control over their running. If you distributed the bots and remote node got hacked, they'd potentially have access to the whole user database (depending on the model).