I currently perform penetration testing of ASP.NET application and trying to exploit Padding Oracle Attack. This AFAIK is based on response code analysis, but both ScriptResource and WebResource axds of the system under test always respond with 200 OK, even if cipher has been invalid. In this case, however, the content of the response is an empty string.
Is it possible to use any of the axd as the oracle in this case? Maybe basing on response content difference.
The Padding Oracle Attack works by being able to distinguish between two cases:
The server failed to decrypt the data because, upon decryption, it did not found a properly formatted padding.
The server found a correct padding, but the decrypted data turned out to be random junk.
There may be several ways for an attacker to get such a distinction. A specific error code from the server is just the easiest to exploit; but any detectable difference is enough. The attack was first published in 2002 (yes, it took 8 years for people to notice that it could be applied to ASP !) and it has been demonstrated on a SSL connection with only a timing difference: the server was decrypting the data, and then was verifying the MAC only if the decryption went fine; the extra 2ms taken by the MAC computation were enough for the attacker to know whether the padding was valid, allowing for direct application of the Padding Oracle Attack.
To answer your original question, the content length can be used. Padbuster notes the status code but I think it detects entirely off the response length.
To answer your reply to Troy, a long ciphertext length does not indicate they are vulnerable. Typically a short ciphertext length does indicate they are vulnerable, but you need to dot net url decode the value then see if modulus 8=0 to see if it's vulnerable. In other words, the length will be a multiple of 8. Usually i'll see one block of ciphertext (16 bytes) end up about 25 bytes once it's dot net url encoded. The fix includes a HMAC (I think), which extends the length and should make one block cipertexts impossible. I can't say this with certainty, as I'm not sure how long the HMAC is and if it works after padding or not.
It sounds to me like the padding oracle patch may have been installed and as a result you're not getting the error codes you were expecting. Have a look at Do you trust your hosting provider and have they really installed the padding oracle patch and see if you can establish this.
Related
I work with Unity and C# - when making multiplayer games I've been told that when it comes to values like positions that are floats, I should use a bit shift operator on them before sending them and reverse the operation on receive. I have been told this not only allows for larger numbers values and is capable of maintaining floating point precision which may be lost. However, if I do not have to, I do not wish to run this operation every time I receive a packet unless I have to. Though the bottle necks seem to be the actual parsing of the bytes received. Especially without message framing and attempting to move from string to byte array. (But that's another story!)
My question are:
Are these valid reason to undergo the operation? Are they accurate statements?
If not should I be running bit shift ops on my floats?
If I should, what are the real reasons to do it?
Any additional information would be most appreciated.
One of the resourcesI'm referring to:
Main reasons for going back and forth to/from network byte order is to combat endianness caused problems, mainly to ensure each byte of multi byte values (long, int but also floats) is read and written in the way giving the same results regardless of architecture. This issue can be theoretically ignored if you are sure you are exchanging data between systems using the same endianness, but that's rather bad idea from very beginning as you are simply creating unneded technological debt and keep unjustified exceptions in the code ("It all works BUT on the same endianness only. What can go wrong?").
Depending on your app architecture you can rewrite the packet payload/data once you receive it and then use that version further in the code. Also note that you need to encode the data again prior sending it out.
I'm wondering how C_DecryptFinal & C_Decrypt are supposed to deal with padding errors.
According to pkcs11 2.20, C_DecryptFinal can return CKR_ENCRYPTED_DATA_INVALID or CKR_ENCRYPTED_DATA_LEN_RANGE,
so I suppose that if padding is invalid, C_DecryptFinal/C_Decrypt return CKR_ENCRYPTED_DATA_INVALID.
Is it correct?
If so, is C_DecryptFinal/C_Decrypt vulnerable to padding-oracle attacks?
Citing the standard (section 11.1.6):
CKR_ENCRYPTED_DATA_LEN_RANGE: The ciphertext input to a decryption
operation has been determined to be invalid ciphertext solely on the
basis of its length. Depending on the operation’s mechanism, this
could mean that the ciphertext is too short, too long, or is not a
multiple of some particular blocksize. This return value has higher
priority than CKR_ENCRYPTED_DATA_INVALID.
CKR_ENCRYPTED_DATA_INVALID: The encrypted input to a decryption
operation has been determined to be invalid ciphertext. This return
value has lower priority than CKR_ENCRYPTED_DATA_LEN_RANGE.
So for block ciphers the CKR_ENCRYPTED_DATA_LEN_RANGE should be returned when the input is not block-aligned.
If the input is block-aligned, the CKR_ENCRYPTED_DATA_INVALID is probably returned in case of wrong padding for the CKM_*_PAD mechanisms.
Thus the padding oracle attack is probably possible.
As the PKCS#7 padding is the only defined padding scheme for block ciphers, it is quite often the responsibility of the application to handle the padding, which leads to what I think should be the answer to your question:
It is up to the application (i.e. "the cryptoki client") not to provide an external attacker (i.e. the "the application client") with any oracle to determine the padding was wrong, regardless of the source of this information (i.e. the cryptoki or the application itself).
It is probably meaningless to protect against the padding oracle attack on the cryptoki interface level (i.e. an attacker inside the application), as such an attacker can decrypt anything at will directly using the appropriate functions.
(Of course it is better to use some form of authenticated encryption and do not need to worry about the padding oracle attack at all)
Desclaimer: I am no crypto expert, so please do validate my thoughts.
I am Implementing the AES128 bit encryption/Decryption in iOS application for sending/receiving data from .net server, I almost done but during unit testing I got some issue in encryption string, some encrypted string are not similar as on .net server, Can say 98 percent strings are correct at both side but issue comes in 2 percent strings , when I match the both side encrypted string then found at iOS end generated string is little short and .net end it is long string. One more thing i found the iOS string is the substring of .net string. When i tried to decrypt the iOS generated encrypted string, it is not decrypted showing null but when I try to decrypt the .net server generated encrypted string (it was larger than the iOS) I am able to se the decrypted string.
Using the same KEY(16 character long at server and iOS end).
could you please suggest the solution or where I am wrong .
Thanks a lot to all.
Original string: "custId=10&mode=1"
KEY= "PasswordPassword"
at iOS encrypted string:
r51TbJpBLYDkcPC+Ei6Rmg==
at .net encrpted string:
r51TbJpBLYDkcPC+Ei6RmtY2fuzv3RsHzsXt/RpFxAs=
padding for encryption = kCCOptionPKCS7Padding;
I followed this tutorial.
http://automagical.rationalmind.net/2009/02/12/aes-interoperability-between-net-and-iphone/
A similar question found on CryptoSE
My Version TL;DR
Essentially .net and iOS both have different implementations, and since the guide you are following is from 2009 I would expect that it is rather out of date by now given there have been at least 1 major revision bump in each of the platforms since then.
Original Answer Gives the following answer:
I can immediately think of four reasons:
They're both not using AES256. I see in the Obj-C document a direct statement that they are using AES256 (unless you deliberately change it), I don't see any statement in the Visual Basic document that says what key size they're using (unless that's what they mean by "Block Bits").
Different keys. AES256 takes a key of 256 bits; there's no standard method to take a five character string and convert that into a 256 bit value. Now, there are a lot of possible methods; there's no particular assurance that they both use the same one.
Different modes of operation. The AES block cipher takes 128-bit values, and translates that into 128-bit values. However, not all our messages can fit into 128 bits, and in addition, sometimes there are other things we'd like to do other than message encryption. A Mode of Operation is a method that takes a block cipher, and uses it as a tool to perform some more generally useful function (such as encrypting a much longer message). There are a number of standard modes of operations, the Obj-C document states that it is using CBC mode; the Visual Basic document has scary sounding words which might be a garbled explination of CBC mode.
IVs. Some modes of operation (such as CBC mode) have the encryptor select an "Initialization Vector" randomly; that can be translated along with the encrypted message (because the decryptor will need that value). One of the things that this Initialization Vector does if you encrypt the message a second time, the second ciphertext will not resemble the first ciphertext at all; that way, someone listening will not be able to deduce that you've just repeated a message. The Obj-C document specifically says that it will pick a random IV (unless to tell give it one yourself).
As you can see, there are a bunch of reasons why the two ciphertexts may be different. One thing you can try: hand the ciphertext from one to the other, and ask them to decrypt it; if they can, you can be pretty sure that both sides are doing basically the same thing.
As you can see, there are a bunch of reasons why the two ciphertexts may be different. One thing you can try: hand the ciphertext from one to the other, and ask them to decrypt it; if they can, you can be pretty sure that both sides are doing basically the same thing.
I'm building a secure payment portal.
We currently have two applications that will be using this. One is a web application, the other a desktop app. Both of these require users to login/authenticate, the same credentials can be used for either application.
I want to build an automatic login mechanism that will fill in all the various login/order details and be able to call this from either app mentioned above. I've been thinking that the best way to do this is to pass this information encrypted through the URL. ie https://mysite.com/TakePayment.aspx?id=GT2jkjh3....
Since we don't want to integrate the payment processing too tightly into the desktop app to reduce our PCI scope, we decided to have it open the browser to a central, secured payment page through a simple shell execute with the full URL causing the default browser to open that page.
Originally we were using AES for the encryption, but this is currently being re-examined as we would prefer not having to give out the key to the end user (AES is symmetric, symmetric encryption = both parties need the private key, why bother even encrypting then since we're going to be distributing the app?) So I'm looking at switching it over to use Public Key Encryption with the built in RSA routines within .NET
After coding up the RSA portion I noticed most examples on the net used 1024bits for the key-length, I went with this and now have our portal working with public key encryption, however the URLs generated are much much longer than when I was using AES so it made me start researching what the max limits for URLs are. http://www.boutell.com/newfaq/misc/urllength.html Says that IE is the limiting browser at about 2048 characters in the path portion. My initial tests with the RSA encryption show my urls will be around 1400 chars long.
My questions boil down to this:
1) Is there a better way for passing information from a desktop app to a website that I'm not thinking of? I'd prefer it be just as easy to use from another web page as it is from the desktop, hence my current solution.
2) Is 1024 bit RSA keys necessary? Or overkill for something like this? A shorter key would mean shorter encrypted text right?
3) Are there any other unforeseen problems with URLs in the 1200-1400 character range? Proxies? Firewalls? Web-Accelerators?
Thanks
Update 12/11/2011:
Come to find out, the method that we ended up going with here ended up biting us in the ass recently (or rather we found out about it today, even though the problem was a very sporadic and difficult one to track down..)
The plain text token that we encrypted was originally rather small, only a hundred bytes or so. This is what resulted in my test URLs being approximately 1400 bytes long. Through feature creep we've been required to add more data to the token, and the average URL length jumped to 1700-1800 in length.
Once the length of our plain text hits 173 characters long and above however, the URL length jumps again, this time up to 2080+ or so, which now causes problems for IE. After some investigation in how RSA encryption works, this should have been totally expected, but was an oversight on my part originally.
We're using 1024 bit RSA encryption, which means that the maximum data block size that can be encrypted is 1024/8 - 24 = 86 bytes, every 86 bytes needs to be "chopped up" and encrypted separately, so at 86 * 2 = 172, we're only encrypting two blocks, above that we're encrypting three, four, five, etc. By passing 172, our cipher text length grew so long the URL's are now too long.. I'm probably messing up the explanation a little here, but that's the general gist of it..
It seems we'll be looking at designing a better way for this to work, as it can be expected they'll want "more features" to be added in the future and thus our token will grow ever larger...
Assuming this is all logged in a database can you not pass the data back and forth using SSL web services. Then in the case of being able to quickly go from the desktop app to the web app make a rpc call to the website to generate a random key, pass that to the user and call a web page using that. Make the key valid for say 10 seconds meaning should a key be captured and broken it will have become invalid?
I have little experience with this kind of thing so I'm expecting many holes to be poked in the idea.
I have an ASP.Net 3.5 platform and windows 2003 server with all the updates.
There is a limit with .Net that it cannot handle more than 260 characters. Moreover if you look it up on web, you will find that IE 6 fails to work if it is not patched at above 100 charcters.
I want to have the rewrite path module to be supported on maximum number of browsers, so I am looking for an acceptable limit to which I can create verbose URL's.
A Url is path + querystring, and the linked article only talks about limiting the path. Therefore, if you're using asp.net, don't exceed a path of 260 characters. Less than 260 will always work, and asp.net has no troubles with long querystrings.
http://somewhere.com/directory/filename.aspx?id=1234
^^^^^^^- querystring
^^^^^^^^^^^^^^^^^^^^^^^^ -------- path
Typically the issue is with the browser. Long ago I did tests and recall that many browsers support 4k url's, except for IE which limits it to 2083, so for all practical purposes, limit it to 2083. I don't know if IE7 and 8 have the limitation, but if you're going to broad compatibility, you need to go for the lowest common denominator.
There is no length limit specified by the W3C, but look here for practical limits
http://www.boutell.com/newfaq/misc/urllength.html
pick your own limit from that.
The default limit in IIS is 16,384 characters
But IE doesn't support more than 2083
More info at link
This article gives the limits imposed by various browsers. It seems that IE limits the URL to 2083 chars, so you should probably stay under that if any of your users are on IE.
Define "optimum" for your application.
The HTTP standard has a limit (it depends on your application):
The HTTP protocol does not place any
a priori limit on the length of a URI.
Servers MUST be able to handle the URI
of any resource they serve, and SHOULD
be able to handle URIs of unbounded
length if they provide GET-based forms
that could generate such URIs. A
server SHOULD return 414 (Request-URI
Too Long) status if a URI is longer
than the server can handle (see
section 10.4.15).
Note: Servers ought to be cautious about depending on URI
lengths above 255 bytes, because some older client or proxy
implementations might not properly support these lengths.
So the question is - what is the limit of your program, or what is the maximum resource identifier size your program needs to perform all its functionality?
Your program should have a natural limit.
If it doesn't you might as well stick it as 16k, as you don't have enough information to define the problem.
-Adam
Short ;-)
The problem is that every web server and every browser has own ideas how long the maximum is. The RFC for the HTTP protocol gives no maximum length. IE limits the get to 2083 characters, the path itself may be at most 2,048 characters. However, this limit is not universal. Firefox claims to support at least up to 65,536, however some people verified that on some platforms even 100,000 characters work. Safari is above 80,000 (tested). Apache server on the other hand has a limit of 4,000. Microsofts Internet Information Server has one being 16,384 (but it is configurable).
My recommendation is to stay below 2'000 characters in any case. This is not guaranteed to work with every browser in the world (especially not older ones), but it will work with all modern browsers. Further I recommend to use POST wherever possible (e.g. avoid using GET for FORM submits - if some users want to simulate a FORM submit via GET, make sure your application supports the desired parameters either via POST or via GET, but when you submit the page yourself via a button or JS, prefer POST over GET).
I think the RFC says 4096 chars but IE truncates down to 2083 characters. Stay well under that to be safe.
Practically, shorter URLs are friendlier.
More information is needed but for normal situations I would say try to keep it under 150 for sure. If for nothing else than pure ascetics, I hate when someone sends me a GI-NORMOUS link...
Are you passing values through the query string? I assume that is why you asked, correct?
What is "optimum" anyway?
GET requests can be several kB in length, so this is entirely subjective.
I'd say - stay within the address bar length of a maximized 1024x768 window to be user friendly.
If you're trying to get people to remember the URL, I wouldn't go more than 60. Use words if possible, because it's easier to remember "www.example.com/this-is-the-url" than "www.example.com/179264". If you're trying to get the page indexed, you could probably go more. The spiders look for words in the title too, and some people may be more likely to click on the link if the URL looks readable.
When you say "Optimum", I think "Easily Accessible To Users", in which case, I think the shorter the URL, the better. I would think 20-30 characters maximum, in that case.