w/kun3fe
Greetings, I hope everything is fine. Today we are going to talk about how to bypass Cloudflare security solution in the most “straight logic” way possible.
We did this work with my dear co-worker Efe Söğüt (kun3fe). It was a scenario that amused us a lot during a private bounty program.
I would like to point out that the methodology I will discuss below will apply to the situations where you are sure that the system you are targeting is behind Cloudflare and is in one of the IP pools that can be accessed as open source.(In our scenario, the system we targeted was using AWS EC2 service.) It may also require customization according to the case you are in. (●’◡’●).
Short and simple, we can proceed with the following main headings about the methodology;
- Detect that the target system is using AWS
- Find IP ranges
- Detect live IP addresses
- Send HTTP requests to the detected IP addresses
- Match the HTTP responses with the expected value
Let’s talk about the technical part.
Detect that the target system is using AWS
In this section, you can actually use one of the thousands ways that vary completely depending on the target system. (but you can also rely on your sixth sense and guess(we do not recommend))
Below I will be talking about how we detect the system we are targeting.
As shown in the image above, while browsing the target system assets, we found that they were using Amazon SES (Simple Email Service) to send support emails.(In this case, we assumed they were using EC2, trusting our guessing skills.(we do not recommend(˶ˆᗜˆ˵)))
Find IP ranges
Since we assume that they are using EC2, I’ll talk about EC2 IP ranges from now on.
We will use IPv4 addresses. We can look at the EC2 IP ranges we got from here. See that there are a few /22 /12 etc. etc.
With the following terminal commands and screenshot, you can see how we extract IPv4 ranges from the “ip-ranges-ec2.json” file that we downloaded to our local.
$ jq -r '.prefixes[] | select(.region == "eu-central-1") | .ip_prefix' ip-ranges-ec2.json
With a simple calculation (not simple at all lol) we can find that there are 3.000.000+ as many IPv4 addresses.
Detect live IP addresses
All we need to do is use the “masscan” to create an uplist by sending requests to the IPv4 ranges we obtained in the previous section.
Below you can see the command and the screenshot we used for this.
$ masscan -iL ip_ranges.txt -p 80,443 --max-rate 10000 -oL scan_results.txt
With the command mentioned above, requests were sent to ports 80 and 443 of 3.516.192 IP addresses in these ranges and the IP addresses with those ports open were written to the file named “scan_results.txt”.
So far we have determined that the system is on AWS. To find the IP address of the system behind Cloudflare, we created an uplist from AWS EC2 IP ranges.
Send HTTP requests to the detected IP addresses
From now on, we will send an HTTP request with the “httpx” tool using the uplist we created.
The HTTP requests may vary depending on the case you are in. The important point here is that the HTTP response to the HTTP request that we will send needs to contain the unique value we expect from the system we are targeting.
This is the HTTP response we used in our case. If we examine the headers of the response, we can see the Cloudflare headers. Also, if we look a bit further down, we can see that the address “mail@metehanyigit.com” which we will use as the match string, is also in the body of the corresponding HTTP response.
If we get the match we want, we can identify the IP addresses behind Cloudflare.
$ httpx-toolkit -request raw_request.txt -match-code 200 -match-string "MATCH STRING" -l scan_results.txt -o httpx_out.txt - threads 300
Above you can see the command we use. Here “raw_request.txt” is the HTTP request that will give the output in the previous screenshots. With the “ -match-string” parameter, we specify the string value we expect from the HTTP response returned from the server.
Match the HTTP responses with the expected value
What we’re going to do is sit back and wait for it to find a match. ૮₍ ˃ ⤙ ˂ ₎ა
At the end of the coffee break, which lasted 1–2 hours for us, we realized that we had found a match.
Of course, first we need to rule out false-positives. We can use burp for this.
What we’re going to do is click on the little pencil icon at the top right and replace the target variable of the HTTP request we showed earlier with the IP addresses we found.
If you look carefully at the HTTP response returned from the server, we can see that the Cloudflare HTTP headers are gone and it returns the same response as the request we created earlier.
Now we can say that we have successfully bypassed the Cloudflare security solution. ₍^ >ヮ<^₎ .ᐟ.ᐟ After that, it’s up to the imagination of the attacker, and we’ll leave it at that.
How to avoid this attack
It’s very easy. All traffic from outside the IP addresses used by Cloudflare should be blocked by Firewall/Reverse Proxy. You can access Cloudflare IP addresses here.