Investigating Open Bullet 2’s HTTP request mode
This is the second article of the series about Open Bullet
2. In the first article, we
gave an overview of Open Bullet 2, a tool frequently used to conduct credential stuffing attacks. In this
blog post, we focus on the Http request
mode of Open Bullet. It offers a set of features that
enable attackers to make GET/POST HTTP requests, including POST login requests automatically. We analyze more in detail its HTTP headers, its TLS
fingerprints, and discuss how it can be detected.
Open Bullet 2 HTTP headers
We use the Stacker
UI to create an
Http request
block. Thus, we can make HTTP requests and observe different signals such as the
HTTP headers used by Open Bullet. By default, the interface looks as follows:
Here, we specified the URL = https://deviceandbrowserinfo.com/http_headers
to study the HTTP headers of the default Open Bullet’s HTTP request bot. We can execute our bot by clicking
on the Debug
button at the top right corner of the screen.
The values returned by https://deviceandbrowserinfo.com/http_headers
show that, by default, Open Bullet 2 only has 4 headers, which is consistent with the
Custom Headers
section in the previous screenshot.
User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Pragma no-cache
Accept */*
Accept-Language en-US,en;q=0.8
We can modify the Custom Headers
section with
the headers taken from Chrome to make the Open Bullet bot look more realistic.
If we run Open Bullet with this new configuration, we notice that these headers have been properly used by the bot when making the request. Indeed, in the screenshot below, we see that https://deviceandbrowserinfo.com/http_headers shows these new headers.
Thus, with a few changes, attackers can easily forge consistent HTTP headers to make Open Bullet requests look like they’re coming from the latest Chrome on MacOS. This can help attackers bypass basic signature-based detection techniques that leverage inconsistent HTTP header combinations.
Nevertheless, is it enough to bypass server-side detection? No!
OpenBullet 2 request mode has an inconsistent TLS/JA3 fingerprint
TLS fingerprinting is a technique used to identify and
categorize clients or servers based on their unique TLS handshake characteristics. It analyzes various
parameters like cipher suites, extensions, and their order in the Client Hello message.
It can be used
for security purposes, in particular for bot detection, to detect HTTP clients that lie about their nature.
For example, a Python HTTP client that would forge its HTTP headers to pretend to be the latest Chrome on
MacOS, like what we did in the previous section with Open Bullet.
We make a request to https://tls.browserleaks.com/tls to visualize information about Open Bullet 2’s default TLS/JA3 fingerprint. We obtain the following information (I truncated certain parts of the payload to make it more readable):
{
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36",
"ja3_hash": "e4d448cdfe06dc1243c1eb026c74ac9a",
"ja3_text": "771,255-49196-49195-49188-49187-49162-49161-49160-49200-49199-49192-49191-49172-49171-49170-157-156-61-60-53-47-10,0-10-11-13-5-18-23,23-24-25,0",
"ja3n_hash": "03511c5f4b9f0d162909cf75a37e0a28",
"ja3n_text": "771,255-49196-49195-49188-49187-49162-49161-49160-49200-49199-49192-49191-49172-49171-49170-157-156-61-60-53-47-10,0-5-10-11-13-18-23,23-24-25,0",
"cipher_suite": [
{
"name": "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
"value": 49195
}
],
"connection_version": [
{
"name": "TLS 1.2",
"value": 771
}
],
"record_version": [
{
"name": "TLS 1.0",
"value": 769
}
],
"handshake_version": [
{
"name": "TLS 1.2",
"value": 771
}
],
"cipher_suites": [
{
"name": "TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
"value": 255
},
{
"name": "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"value": 49196
},
// ... Removed a few cipher suites to decrease the image size
{
"name": "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
"value": 10
}
],
"extensions": [
{
"name": "supported_groups",
"value": 10,
"data": {
"named_groups": [
{
"name": "secp256r1",
"value": 23
},
{
"name": "secp384r1",
"value": 24
},
{
"name": "secp521r1",
"value": 25
}
]
}
},
{
"name": "ec_point_formats",
"value": 11,
"data": {
"ec_point_format_list": [
{
"name": "uncompressed",
"value": 0
}
]
}
},
{
"name": "signature_algorithms",
"value": 13,
"data": {
"algorithms": [
{
"name": "rsa_pkcs1_sha256",
"value": 1025
},
{
"name": "rsa_pkcs1_sha1",
"value": 513
},
// ...
{
"name": "ecdsa_secp384r1_sha384",
"value": 1283
},
{
"name": "ecdsa_secp521r1_sha512",
"value": 1539
}
]
}
},
{
"name": "status_request",
"value": 5,
"data": {
"status_type": [
{
"name": "OCSP",
"value": 1
}
],
"responder_id_list": 0,
"request_extensions": 0
}
},
{
"name": "signed_certificate_timestamp",
"value": 18
},
{
"name": "extended_master_secret",
"value": 23
}
]
}
If you do the same test with a real Chrome browser, you will notice significantly different results. The reason is simple, as pointed out by Benjamin Brundage, founder of Synthient, Open Bullet 2 hardcodes the TLS cipher suite to the one that was sent by Firefox as of December 2020:
Thus, even though we modified the headers of our bots to pretend to be the latest Chrome on MacOS, Open Bullet 2 still has TLS cipher suites linked to an old Firefox version.
Can attackers modify their TLS fingerprint in OpenBullet 2?
Yes, Open Bullet 2 offers the possibility to provide your
own list of TLS cipher suites if you select Use Custom Cipher Suites
.
While this option may not be enough to create a fully consistent TLS fingerprint, this may help attackers bypass static JA3/TLS fingerprint blocklist.
Indeed, as explained in this blog post, CDNs often rely on blocklists and not allowlists to decide whether or not a request with a specific TLS fingerprint should be allowed. While using allowlist could help to catch more bots, in particular, if they randomize their fingerprint, it would be riskier and could cause false positives whenever new legitimate fingerprints appear (cf screenshot below). Thus, attackers could still randomize their TLS cipher suites in Open Bullet to bypass certain TLS fingerprinting blocklists.
How can I detect Open Bullet 2 when used in HTTP request mode?
Even in HTTP request mode, i.e. without using an instrumented browser, Open Bullet 2 can still be used to conduct successful credential stuffing attacks if the websites or the mobile applications targeted are not properly secured.
You can use different techniques to detect and stop Open Bullet 2 in HTTP request mode:
- Force JS execution: you can force the user to execute a script before he can attempt to log in. While this may seem easy, be careful of your implementation. Indeed, if your script is used to set a cookie or generate a token, keep in mind that the attacker may be tempted to reuse it or to extract/generate it statically without actually executing your script.
- Behavioral analysis: you can apply behavioral analysis at different granularities, e.g. on the IP address, on the session (based on a cookie), or per username/email. The main drawback of behavioral approaches is that they may not be effective from the first request and may take some time to detect an attacker. Moreover, remember that credential stuffing attacks are often distributed across thousands of IPs using proxies.
- CAPTCHAs: You can force users to solve a CAPTCHA before they can attempt to log in. However, CAPTCHAs are known to be bad from a UX perspective. Moreover, Open Bullet 2 integrates with dozens of CAPTCHA farms, which means that an attacker just has to provide an API key to be able to automatically solve most of the mainstream CAPTCHAs on the market.
- Bot management solution: Keeping up with bots may be a full-time job. You may want to use a bot management solution such as DataDome to take care of it. These kinds of products leverage thousands of signals, in real-time, to ensure bots are blocked from the first request.
Conclusion
In this second blog post of our series about Open Bullet
2, we analyzed the Http request
feature that can be used to make HTTP POST login requests by
bots. In particular, we analyzed its HTTP headers, its default TLS fingerprint, and showed that by default,
it uses an outdated TLS cipher suite linked to a Firefox version of 2020.
In the next blog posts of this series, we will continue to investigate Open Bullet 2, in particular the features that enable attackers to make login attempts or to avoid bot detection techniques.