-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
There is a http request splitting vulnerability #1798
Comments
Can you elaborate what you think Zeek should be doing in this case instead? What Zeek sees here from the client is this:
Afaict, Zeek is actually doing as good as it can here: the |
After you send this request, check
However, ZEEK produced three lines of logs. And the second line marks HTTP method as
Using Here is a similar example, you can have a look. |
Yeah, I understand what's happening and see the multiple entries in
The thing is: That's what |
I would argue on the side of what Robin's saying here. The intent of the Zeek logs is frequently to take the incoming data and, as accurately as possible, give a representation in logs. I believe that in this case Zeek did exactly that and gave an accurate representation of what was on the wire. If Zeek only printed the single log line as you suggested, it would be confusing because there are legitimately more requests there and they would have been hidden. |
But more importantly, ZEEK records a request method as |
Because Zeek never actively participates in transactions, but only sits to the side and observes them we have to acknowledge reality and the reality is that not all of the HTTP verbs that people use are defined in any RFC. If you want to do detection activity, you can create the list of HTTP verbs that you consider to be valid and watch for anything that diverges. The argument that you are making would put us in the position where we wouldn't even be able to do detection of someone attempting a request splitting vulnerability. Actually, now that I think about it, we already generate "Weirds" whenever a request is seen that isn't in the list defined here: zeek/scripts/base/protocols/http/main.zeek Line 117 in 9aadc7e
|
Hi @wubonetcn I just took a look at the talk that you referenced. And I think that what you show here is actually not buggy behavior. From my understanding, HTTP request smuggling works by you having several different
where different software interprets the content-length differently. In the example that you give, there is only one content-length - so there only is one viable interpretation, which Zeek chooses. I just did a quick test what happens when several different Content-length headers are present, using...
The resulting log here is not optimal, we definitely get confused:
and weird.log:
My read of RFC7230 is that several content-length headers with different values is just completely illegal, and that, in that case, a server (or client) should stop processing the data. Since we are a man-in-the-middle-observer we don't really have the option of stopping a connection that does that. My feeling is that we should report a weird if we see several different content-length headers. I am not sure what we should do from a parsing point of view in these cases - do you have any opinion of that? In any case - I don't think that this, as originally reported, is an issue. Please let me knof if I am mistaken about this. |
In fact, you can easily solve this problem. |
we have to use the content-length to parse requests. As, by the way, the talk you referenced makes clear. Without the content-length you cannot decide when a request ends - and there can (and will) be several HTTP requests in one connection. |
For example, how should Zeek parse the result of the following curl command without using Content-length:
This results in 4 POST lines in 2 requests - that are correctly parsed. There also is no ambiguity what should happen here - just as there is none in your example. The only problem that I can see is having two content-lengths in one http request - which is an undecidable problem. |
Oh! The request splitting is due to multiple repeated headers. The original example didn't do that. I definitely agree that it would make sense to do a weird if there are multiple content-length headers. That's definitely just another one of those undecidable situations that we inevitably run into. |
Yes, it's not only your software that has this problem, but also many software. |
@wubonetcn - the difference is that they are an active participant. We are a passive participant. We cannot terminate a connection, like a proxy can. So - we have to choose to parse one variant if we are presented with multiple content-length headers. The only alternative is to stop processing the HTTP connection completely - which also does not seem like the optimal way to do it, since that means that no more information about the connection will be logged. |
I did an experiment before. Using Wireshark's HTTP tracking function, there will be no multiple parsing results. They can handle this problem well. |
If you think that wireshark does this differently to Zeek, please provide a pcap where this is the case. |
The example you provided can be used. Red is the request and blue is the response. The red request is complete and not split. |
This is not true - you misunderstand the output of Wireshark. Red/blue is just the direction of traffic in this case (follow TCP stream). If you look at the output above, wireshark does indeed split this into three different requests - just as Zeek does. |
Oh, it seems that I read Wireshark wrong.It seems that we need to find other solutions. |
As mentioned by Robin in the second comment - for your report there actually is no problem. Wireshark, Zeek, and proxies will all interpret this as 3 different requests - in accordance with the standards. The problem that we do have is that we cannot decide what to do if we get a request of the form:
In this case, we have no way of knowing if the software at the other end of the connection will interpret this with content-length 1, or content-length 10 - but we do have to decide for one of the choices. The RFC just tells you that this is invalid - which is true, but does not directly help us. We can raise a weird - but we still do have to decide what to do parsing-wise. And this is just undecidable - there is no correct answer. |
OK,this is really a difficult problem to solve. I'll contact you if I can think of a solution. |
You may also be interested in the package
https://github.com/precurse/zeek-httpattacks
-s
…On Thu, Sep 30, 2021 at 7:06 AM wubonetcn ***@***.***> wrote:
OK,this is really a difficult problem to solve. I'll contact you if I can
think of a solution.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#1798 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADRHAWCRDOKXMJO4P5KYWBLUERVFBANCNFSM5EV47F3A>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Thank you. The script you provide can detect such events and generate a new event record. However, we use ZEEK as an HTTP traffic recorder. This security event detection is done by our other programs. ZEEK provides the original HTTP input. The problem now is that ZEEK will generate three records from an HTTP connection. In this way, we will also get 3 wrong inputs, which will lead to problems in our test results. Of course, other scripts based on HTTP statistics will also make errors, such as the HTTP flood detection script provided by ZEEK. Such scripts based on request quantity statistics will make errors because more records are generated. |
My suggestion is that an HTTP connection only generates one record, even if there are multiple transmissions in the HTTP connection. ZEEK, as a faithful recorder, should be regarded as the same connection as long as the HTTP connection is not disconnected. |
If you mean this as "you should only record one http log line for each http TCP connection" - I do not see how this is viable/desirable/reasonable. One HTTP connection can contain thousands of requests - people use Zeek because they want this logged. |
As mentioned above - Zeek produces the output that is required by the HTTP RFCs. For your example there is no ambiguity around this - it is 3 requests, not one. So you do get the correct output - Zeek records the traffic as it happened (thus, as 3 requests, just as Wireshark, e.g., parses it) Why do you want this logged as one request? Why do you think it should be logged as such? |
Didn't you see the previous discussion? |
rsmmr commented yesterday • Using Content-Length to segment HTTP requests is dangerous The thing is: That's what Content-Length is for. The receiving server will likewise use it to segment the client's data. I don't see how else Zeek (or the server) could parse this otherwise. What would you suggest? Rsmmr has confirmed. I don't want to answer this question again. The solution I proposed is just a solution idea, which does not mean that you will eventually do so. |
Sorry, I don't follow what you're saying. I'll go ahead and close the ticket as everything's working as expected. |
By sending a specific HTTP POST request, ZEEK will split a request into multiple and split the wrong fields. This will invalidate any ZEEK HTTP based security analysis(Including ZEEK's internal security plug-ins).
POC
Detailed information
ZEEK version
Start ZEEK
Send normal request
ZEEK generates 1 log
The request method is POST, the host is 192.168.220.132, and the uri is / b.html
Send poc
ZEEK generates HTTP logs with 3 errors
The first display request method is POST, host is - uri is / a.html
The second display request method is bc, host is - uri is abc
The third display request method is POST, the host is 192.168.220.132, and the uri is / a.html
Obviously, ZEEK divides an HTTP request into three, and the request method, request host and request URI are misplaced. This will invalidate any ZEEK HTTP based analysis. HTTP request splitting vulnerability exists.
The text was updated successfully, but these errors were encountered: