As Crypto currency technologies are becoming more and more prevalent, as the time is passing by, and banks will soon start adopting them. Ethereum blockchain and other complex blockchain programs are relatively new and highly experimental. Therefore, we should expect constant changes in the security landscape, as new bugs and security risks are discovered, and new best practices are developed [1].This article is going to discuss how to perform a source code review in Ethereum Smart Contracts (SCs) and what to look for. More specifically we are going to focus in specific keywords and how to analyse them.
The points analysed are going to be:
User supplied input filtering, when interacting directly with SC
Interfacing with external SCs
Interfacing with DApp applications
SC formal verification
Wallet authentication in DApp
SC Programming Mindset
When designing an SC ecosystem (a group of SCs, constitutes an ecosystem) is it wise to have some specific concepts and security design principles in mind. SC programming requires a different engineering mindset than we may be used to. The cost of failure can be high, and change can be difficult, making it in some ways more similar to hardware programming or financial services programming than web or mobile development.
When programming SCs we should be able to:
Design carefully roll outs
Keep contracts simple and modular
Be fully aware of blockchain properties
Prepare for failure
Key Security Concepts For SCs Systems
More specifically it is mandatory and the responsible thing to is to take into consideration the following areas:
SC ecosystem monitoring e.g. monitor for unusual transactions etc.
SC ecosystem governance/admin e.g. by using proxy SC that follow best practices etc.
SC formal verification of all the SCs interacting with
SC modular/clean coding e.g. use comments and modular code etc.
SC ecosystem code auditing by an external independent 3rd party
SC ecosystem system penetration testing by an external independent 3rd party
Note: At this point we should point out that it is important that DApp smart contract interaction should also be reviewed.
SCs User Input Validation
Make sure you apply user input validation on a DApp and SC level. Remember that on-chain data are public and an adversary can interact with a SC directly, by simply visiting an Ethereum explorer in etherscan.io, the following screenshots demonstrate that.
Below we can see an example of a deployed contract:
Simple by clicking in the SC link we can interact with the contract:
Note: Above we can see the upgrade function call and various other Admin functions. Of course is not that easy to interact with them.
It is also known that etherscan.io provides some experimental features to decompile the SC code:
If we click the decompile code we get this screen below:
Below we can see how a DApp or wallet can interact with a SC:
There are five categories of Ethereum wallets that can interact with DApps:
Browser built-in (e.g. Opera, Brave etc)
Browser extension (e.g. MetaMask )
Mobile wallets (e.g. Trust, Walleth, Pillar etc.)
Account-based web wallets (e.g. Fortmatic, 3box etc.)
Hardware wallets (e.g. Ledger, Trezor etc.)
Then there is a larger category of wallets that cannot integrate with DApps include generic wallet apps that lack the functionality to integrate with smart contracts. Different wallets have a different user experience to connect. For example, with MetaMask you get a Connect pop up. With mobile wallets, you scan a QR code. So phishing attacks take a different for e.g. an attacker can spoof a QR code, through online free QR generators etc. When assessing a DApp the architecture is of paramount importance. A user with a Metamask plugin can use it to connect to the DApp. The DApp automatically will associate the interaction with the user public key to run various tasks.
For a Web based DApp we can use traditional filtering methods. But for SCs using Solidity we can use assert and require are as convenience functions that check for conditions (e.g. a user supplies input and the mentioned functions check if the conditions are met). In cases when conditions are not met, they throw exceptions, that we help us handle the errors.
These are the cases when Solidity creates assert-type of exceptions when we [3]:
Invoke Solidity assert with an argument, showing false.
Invoke a zero-initialized variable of an internal function type.
Convert a large or negative value to enum.
We divide or modulo by zero.
We access an array in an index that is too big or negative.
The require Solidity function guarantees validity of conditions that cannot be detected before execution. It checks inputs, contract state variables and return values from calls to external contracts.
In the following cases, Solidity triggers a require-type of exception when [3]:
We call require with arguments that result in false.
A function called through a message does not end properly.
We create a contract with new keyword and the process does not end properly.
We target a codeless contract with an external function.
We contract gets Ether through a public getter function.
We .transfer() ends in failure.
Generally speaking when handling complex user input and run mathematical calculations it is mandatory to use external libraries from 3rd partyaudited code. A code project to look into would be SafeMath from OpenZeppelin. SafeMath is a wrapper over Solidity’s arithmetic operations with added overflow checks. Arithmetic operations in Solidity wrap on overflow. This can easily result in bugs, because programmers usually assume that an overflow raises an error, which is the standard behavior in high level programming languages. SafeMath restores this intuition by reverting the transaction when an operation overflows.
SC External Calls
Calls to untrusted 3rd party Smart Contracts can introduce several security issues. External calls may execute malicious code in that contract or any other contract that it depends upon. As such, every external call should be treated as a potential security risk. Solidity's call function is a low-level interface for sending a message to an SC. It returns false if the subcall encounters an exception, otherwise it returns true. There is no notion of a legal call, if it compiles, it's valid Solidity.
Especially when the return value of a message call is not checked, execution will resume even if the called contract throws an exception. If the call fails accidentally or an attacker forces the call to fail, this may cause unexpected behavior in the subsequent program logic. Always make sure to handle the possibility that the call will fail by checking the return value of that function [4].
Reentrancy (Recursive Call Attack)
One of the major risks of calling external contracts is that they can take over the control flow. In the reentrancy attack (a.k.a. recursive call attack) calling external contracts can take over the control flow, and make changes to your data that the calling function wasn’t expecting. A reentrancy attack occurs when the attacker drains funds from the target contract by recursively calling the target’s withdraw function [4].
Below we can see a schematic representation:
Note: For more information on this type of attack please see [4]
SC Denial of Service Attacks
Each block has an upper bound on the amount of gas that can be spent, and thus the amount computation that can be done. This is the Block Gas Limit. If the gas spent exceeds this limit, the transaction will fail.
This leads to a couple possible Denial of Service vectors:
Gas Limit DoS on a Contract via Unbounded Operations
According the Solidity docs [7], there exists a special variant of a message call, named delegatecall which is identical to a message call apart from the fact that the code at the target address is executed in the context of the calling contract and msg.sender and msg.value do not change their values.
This means that a contract can dynamically load code from a different address at runtime. Storage, current address and balance still refer to the calling contract, only the code is taken from the called address. This makes it possible to implement the “library” feature in Solidity: Reusable library code that can be applied to a contract’s storage, e.g. in order to implement a complex data structure.
Improper security use of this function was the cause for the Parity Multisig Wallet hack in 2017. This function is very useful for granting our contract the ability to make calls on other contracts, as if that code were a part of our own contract. However, using delegatecall() causes all public functions from the called contract to be callable by anyone. Because this behavior was not recognized when Parity built its own custom libraries.
Epilogue
Writing secure smart code is a lot of work and can be very complex.
In the recent past we encountered two relatively new types of attacks: External Service Interaction (ESI) and Out-of-Band Resource Loads (OfBRL).
An ESI[1] occurs only when a web application allows interaction with an arbitrary external service.
OfBRL[6] arises when it is possible to induce an application to fetch content from an arbitrary external location, and incorporate that content into the application's own response(s).
Taxonomy Note (2026): Both ESI and OfBRL are now classified under OWASP A10:2021 — SSRF and map to CWE-918 (Server-Side Request Forgery). ESI also maps to CWE-441 (Unintentional Proxy or Intermediary).
The Problem with OfBRL
The ability to request and retrieve web content from other systems can allow the application server to be used as a two-way attack proxy (when OfBRL is applicable) or a one-way proxy (when ESI is applicable). By submitting suitable payloads, an attacker can cause the application server to attack, or retrieve content from, other systems that it can interact with. This may include public third-party systems, internal systems within the same organization, or services available on the local loopback adapter of the application server itself. Depending on the network architecture, this may expose highly vulnerable internal services that are not otherwise accessible to external attackers.
The Problem with ESI
External service interaction arises when it is possible to induce an application to interact with an arbitrary external service, such as a web or mail server. The ability to trigger arbitrary external service interactions does not constitute a vulnerability in its own right, and in some cases might even be the intended behavior of the application. However, in many cases, it can indicate a vulnerability with serious consequences.
Figure 1 — ESI (one-way) vs OfBRL (two-way) attack paths
The Verification
We do not have ESI or OfBRL when:
In Collaborator, the source IP is our browser IP (the server didn't make the request).
There is a 302 redirect from our host to the Collaborator (i.e. our source IP appears in the Collaborator logs, not the server's).
Below we can see the original configuration in the repeater, followed by the modified configuration for the test. In the original request, the Host header reflects the legitimate domain. In the test request, we replace it with our Collaborator payload or target host.
Original request
GET / HTTP/1.1
Host: our_vulnerableapp.com
Pragma: no-cache
Cache-Control: no-cache, no-transform
Connection: close
Malicious requests
GET / HTTP/1.1
Host: malicious.com
Pragma: no-cache
Cache-Control: no-cache, no-transform
Connection: close
GET / HTTP/1.1
Host: 127.0.0.1:8080
Pragma: no-cache
Cache-Control: no-cache, no-transform
Connection: close
If the application is vulnerable to OfBRL, the reply is going to be processed by the vulnerable application, bounce back to the sender (the attacker) and potentially load in the context of the application. If the reply does not come back to the sender, then we might have an ESI, and further investigation is required.
The RFCs Updated
It usually is a platform issue and not an application one. In some scenarios when we have, for example, a CGI application, the HTTP headers are handled by the application (i.e. the app is dynamically manipulating the HTTP headers to run properly). This means that HTTP headers such as Location and Host are handled by the app and therefore a vulnerability might exist. It is recommended to run HTTP header integrity checks when you own a critical application that is running on your behalf.
For more information on the subject, read RFC 9110 (HTTP Semantics, June 2022) [2] and RFC 9112 (HTTP/1.1 Message Syntax and Routing) [2b], which supersede the obsolete RFC 2616. The Host request-header field specifies the Internet host and port number of the resource being requested, as obtained from the original URI. The Host field value MUST represent the naming authority of the origin server or gateway given by the original URL. This allows the origin server or gateway to differentiate between internally-ambiguous URLs, such as the root "/" URL of a server for multiple host names on a single IP address.
RFC Update: RFC 2616 was obsoleted in 2014 by RFCs 7230–7235, which were themselves superseded by RFCs 9110–9112 in June 2022. All references in this article now point to the current standards.
When TLS is enforced throughout the whole application (even the root path /), an ESI or OfBRL is significantly harder to exploit, because TLS performs source origin authentication — as soon as a connection is established with an IP, the protocol guarantees that the connection will serve traffic only from the original certificate holder. More specifically, we are going to get an SNI error.
SNI prevents what's known as a "common name mismatch error": when a client device reaches the IP address of a vulnerable app, but the name on the TLS certificate doesn't match the name of the website. SNI was added to the IETF's Internet RFCs in June 2003 through RFC 3546, with the latest version in RFC 6066. The current TLS 1.3 specification is RFC 8446[10].
ECH Warning (2025+): Encrypted Client Hello (ECH), specified in RFC 8744 and actively being deployed by major browsers and CDNs, encrypts the SNI field within the TLS handshake. This means that SNI-based filtering and inspection at network perimeters becomes ineffective when ECH is in use. Security teams should account for this when relying on SNI as a defensive control.
Figure 2 — TLS/SNI protection mechanism (and its ECH caveat)
The option to trigger an arbitrary external service interaction does not constitute a vulnerability in its own right, and in some cases it might be the intended behavior of the application. But we as hackers want to exploit it — what can we do with an ESI or an Out-of-Band Resource Load?
The Infrastructure
Well, it depends on the overall setup. The highest-value scenarios are the following:
The application is behind a WAF (with restrictive ACLs)
The application is behind a UTM (with restrictive ACLs)
The application is running multiple applications in a virtual environment
The application is running behind a NAT
The application runs in a cloud environment with metadata endpoints accessible from localhost
The application runs in a containerized environment (Docker/Kubernetes) with internal service discovery
In order to perform the attack, we simply inject our host value in the HTTP Host header (hostname including port).
Burp Professional edition has a feature named Collaborator. Burp Collaborator is a network service that Burp Suite uses to help discover vulnerabilities such as ESI and OfBRL [3]. A typical example would be to use Burp Collaborator to test if ESI exists.
As hacker-artists, we now think about how to exploit this. The scenarios are: [7][8]
Attempt to load the local admin panels.
Attempt to load the admin panels of surrounding applications.
Attempt to interact with other services in the DMZ.
Attempt to port scan localhost.
Attempt to port scan DMZ hosts.
Use it to exploit IP trust and run a DoS attack against other systems.
Access cloud metadata endpoints to extract IAM credentials or instance identity tokens.
Probe Kubernetes API or container sidecar services (e.g. Envoy admin on localhost:15000).
A good tool for automating this is Burp Intruder [4]. Using Sniper mode, we can:
Rotate through different ports, using the vulnapp.com domain name.
Rotate through different ports, using the vulnapp.com external IP.
Rotate through different ports, using the vulnapp.com internal IP, if applicable.
Rotate through different internal IPs in the same domain, if applicable.
Rotate through different protocols (may not always work).
Brute-force directories on identified DMZ hosts.
Burp Intruder — scanning surrounding hosts
GET / HTTP/1.1
Host: 192.168.1.§§
Pragma: no-cache
Cache-Control: no-cache, no-transform
Connection: close
Burp Intruder — port scanning surrounding hosts
GET / HTTP/1.1
Host: 192.168.1.1:§§
Pragma: no-cache
Cache-Control: no-cache, no-transform
Connection: close
Burp Intruder — port scanning localhost
GET / HTTP/1.1
Host: 127.0.0.1:§§
Pragma: no-cache
Cache-Control: no-cache, no-transform
Connection: close
Modern Attack Vectors New 2026
Since the original publication of this article, several high-impact attack surfaces have emerged that directly exploit ESI/OfBRL primitives:
Cloud metadata endpoint exploitation
Cloud providers expose instance metadata via link-local addresses. When a vulnerable application can be coerced into making requests to these endpoints via Host header injection, an attacker can extract IAM credentials, service account tokens, instance identity documents, and network configuration details.
GET / HTTP/1.1
Host: 169.254.169.254
# AWS IMDSv1 — returns IAM role credentials
GET / HTTP/1.1
Host: metadata.google.internal
# GCP — returns service account tokens
GET / HTTP/1.1
Host: 169.254.169.254
Metadata: true
# Azure — requires Metadata header (may not work via Host injection alone)
Mitigation: AWS IMDSv2 mitigates this by requiring a PUT request with a TTL-bounded token (hop limit = 1). GCP Compute VMs support a similar metadata concealment mechanism. Ensure your cloud instances enforce these protections.
Container and Kubernetes exploitation
In containerized environments, the application server often has network access to internal Kubernetes services that are never meant to be internet-facing:
GET / HTTP/1.1
Host: kubernetes.default.svc:443
# K8s API server — may leak secrets, pod specs, RBAC config
GET / HTTP/1.1
Host: 127.0.0.1:15000
# Envoy sidecar admin — config dump, cluster endpoints, stats
GET / HTTP/1.1
Host: 127.0.0.1:9090
# Prometheus metrics — may expose internal service topology
Practical cache poisoning (Kettle, 2018)
James Kettle's 2018 PortSwigger research on practical web cache poisoning significantly expanded the attack surface understanding for Host header injection. His work demonstrated that unkeyed HTTP headers (including Host, X-Forwarded-Host, and X-Forwarded-Scheme) can be used to poison shared caches (CDNs, reverse proxies) at scale, affecting all users served by the poisoned cache entry. This research formalized the technique that was previously theoretical into a repeatable, high-impact attack chain.
Figure 4 — Cache poisoning via Host header injection
What Can You Do
The full exploitation analysis — this vulnerability can be used in the following ways:
Bypass restrictive UTM ACLs
Bypass restrictive WAF rules
Bypass restrictive firewall ACLs
Perform cache poisoning
Fingerprint internal infrastructure
Perform DoS exploiting IP trust
Exploit applications hosted on the same machine (multiple app loads)
Extract cloud IAM credentials via metadata endpoints
Map Kubernetes cluster topology via internal service discovery
Exfiltrate data through DNS-based out-of-band channels
The impact of a maliciously constructed response can be magnified if it is cached either by a shared web cache or the browser cache of a single user. If a response is cached in a shared web cache, such as those commonly found in proxy servers or CDNs, then all users of that cache will continue to receive the malicious content until the cache entry is purged. Similarly, if the response is cached in the browser of an individual user, that user will continue to receive the malicious content until the cache entry expires [5].
What Can't You Do
You cannot perform XSS or CSRF exploiting this vulnerability, unless certain conditions apply (e.g. the poisoned response injects attacker-controlled JavaScript into a cached page, or the application reflects the Host header value into HTML output without encoding).
The Fix Updated
If the ability to trigger arbitrary ESI or OfBRL is not intended behavior, then you should implement a whitelist of permitted URLs, and block requests to URLs that do not appear on this whitelist [6]. Running host integrity checks is also recommended.
Review the purpose and intended use of the relevant application functionality, and determine whether the ability to trigger arbitrary external service interactions is intended behavior. If so, be aware of the types of attacks that can be performed via this behavior and take appropriate measures. These measures might include blocking network access from the application server to other internal systems, and hardening the application server itself to remove any services available on the local loopback adapter.
More specifically, we can:
Apply egress filtering on the DMZ
Apply egress filtering on the host (iptables/nftables rules, or cloud security group outbound rules)
Apply whitelist IP restrictions in the application
Apply blacklist restrictions in the application (not recommended — incomplete by nature)
Validate and normalize the Host header at the reverse proxy layer before it reaches the application (e.g. Nginx server_name directive with explicit hostnames, reject requests with unknown Host values)
Use X-Forwarded-Host with strict allowlisting rather than trusting the raw Host header — and ensure the reverse proxy strips any client-supplied X-Forwarded-* headers before adding its own
Enforce IMDSv2 on cloud instances (hop limit = 1, PUT-based token acquisition) to block Host header SSRF to metadata endpoints
Apply Kubernetes NetworkPolicies to restrict pod-to-pod and pod-to-service communication to only what's necessary
Deploy egress proxies for any application that legitimately needs to make outbound HTTP requests — force all outbound traffic through a proxy with domain allowlisting
In this tutorial we are going to talk on how to cause maximum down time (including operational recovery processes) in anything that uses the word Web, this is also known as a Denial o Service Attack. Using this knowledge for malicious purposes is not something I am recommending or approve and I have zero accountability on how you use this knowledge. This is the reason I am providing also with countermeasures on the end of the post.
What Is The Landscape
In the past we have seen many Denial of Service attacks, but most of them were not very sophisticated. A very good example would be the Low Orbit Ion Cannon (LOIC). LOIC performs a DoS attack (or when used by multiple individuals, a DDoS attack) on a target site by flooding the server with TCP or UDP packets with the intention of disrupting the service of a particular host. People have used LOIC to join voluntary botnets.[2]
All these attacks as stated in previous post do not really take advantage of the 7th layer complexity of the Web and therefore are not so effective as they could be. A very good post exists in the Cloudflare blog named Famous DDoS Attacks [3].
A few of the famous attacks are:
The 2016 Dyn attack
The 2015 GitHub attack
The 2013 Spamhaus attack
The 2000 Mafiaboy attack
The 2007 Estonia attack
Improving DoS and DDoS attacks
In order to improve or understand better what is possible while conducting a DoS attack, we have to think like a Web Server, Be a Web Server, Breath like a Web Server!!
Well what does a server breath? But of course HTTP, so what if we make the Web Server start breathing a lot of HTTP/S, that would be amazing.
This is how we can over dose with HTTP a web server:
HTTP Connection reuse
HTTP Pipelining
Single SSL/TLS handshake
But lets go a step further and expand on that, what else can we do to increase the impact? But of course profile the server and adjust the traffic to something that can be processed e.g. abuse vulnerable file upload functionality, SQLi attacks with drop statements etc.
HTTP connection reuse
HTTP persistent connection, also called HTTP keep-alive, or HTTP connection reuse, is the idea of using a single TCP connection to send and receive multiple HTTP requests/responses, as opposed to opening a new connection for every single request/response pair.
The newer HTTP/2 protocol uses the same idea and takes it further to allow multiple concurrent requests/responses to be multiplexed over a single connection.
HTTP 1.0, connections are not considered persistent unless a keep-alive header is included, although there is no official specification for how keepalive operates. It was, in essence, added to an existing protocol. If the client supports keep-alive, it adds an additional header to the request:
Connection: keep-alive
Then, when the server receives this request and generates a response, it also adds a header to the response:
Connection: keep-alive
Following this, the connection is not dropped, but is instead kept open. When the client sends another request, it uses the same connection. This will continue until either the client or the server decides that the conversation is over, and one of them drops the connection.
In HTTP 1.1, all connections are considered persistent unless declared otherwise. The HTTP persistent connections do not use separate keepalive messages, they just allow multiple requests to use a single connection.
If the client does not close the connection when all of the data it needs has been received, the resources needed to keep the connection open on the server will be unavailable for other clients. How much this affects the server's availability and how long the resources are unavailable depend on the server's architecture and configuration. Yes dear reader I know what are you thinking, how can you the humble hacker, the humble whitehat reader can use this knowledge to bring down your home web server for fun? Well there are good news. In Python there are various functions provided for instantiating HTTP keepalive connections within urllib3 library, such as ConnectionPools.
keep_alive – If True, adds ‘connection: keep-alive’ header.
accept_encoding – Can be a boolean, list, or string. True translates to ‘gzip,deflate’. List will get joined by comma. String will be used as provided.
user_agent – String representing the user-agent you want, such as “python-urllib3/0.6”
Note: If you are a proxy person, you can use the Match and Replace functionality on Burp Pro Suite to add or replace a the keepalive header. Bur then, your client (aka. the browser would have to know how to handle the received content). Better to write a Python template to handle the interaction.
HTTP Pipelining
HTTP pipelining is a technique in which multiple HTTP requests are sent on a single TCP (transmission control protocol) connection without waiting for the corresponding responses. The technique was superseded by multiplexing via HTTP/2, which is supported by most modern browsers.
See following diagram for pipeline :
HTTP pipelining requires both the client and the server to support it. HTTP/1.1 conforming servers are required to support pipelining (Pipelining was introduced in HTTP/1.1 and was not present in HTTP/1.0). This does not mean that servers are required to pipeline responses, but that they are required not to fail if a client chooses to pipeline requests. Interesting behavior!!!!!!!!!
Note: Most of the servers execute requests from pipelining clients in the same fashion they would from non-pipelining clients. They don’t try to optimize it.
Again, yes dear reader I know what are you thinking, how can you the humble blackhat hacker, the humble hacktivist reader can use this knowledge to bring down your home web server for fun? Well there are more good news.
Some Python frameworks do support HTTP/2 aka HTTP pipelining , Mouxaxaxa. As of late 2017 there are two Python frameworks that directly support HTTP/2, namely Twisted and Quart with only the latter supporting server-push.
Quart can be installed via pipenv or pip:
$ pipenv install quart
$ pip install quart
This requires Python 3.7.0 or higher (see python version support for reasoning).
Also another library that supports Python HTTP/2 connectivity is hyper. hyper is a Python HTTP/2 library, as well as a very serviceable HTTP/1.1 library.
To begin, you will need to install hyper. This can be done like so:
$ pip install hyper
From the terminal you can launch a request by typing:
>>> from hyper import HTTPConnection
>>> c = HTTPConnection('http2bin.org')
>>> c.request('GET', '/')
1
>>> resp = c.get_response()
Used in this way, hyper behaves exactly like http.client classic Python client. You can make sequential requests using the exact same API you’re accustomed to. The only difference is that HTTPConnection.request() may return a value, unlike the equivalent http.client function. If present, the return value is the HTTP/2 stream identifier.
In HTTP/2, connections are divided into multiple streams (due to pipelining). Each stream carries a single request-response pair. You may start multiple requests before reading the response from any of them, and switch between them using their stream IDs. Note: Be warned: hyper is in a very early alpha. You will encounter bugs when using it. If you use the library, provide feedback about potential issues and send to the creator.
Making Sense
By dramatically speeding up the number of payloads per second send to the server we increase the chance to crash the system for the following reasons:
Multiple HTTP/2 connections sending requests such as the following would cause significant resource allocation, both in the server and the database:
File upload requests, with large files to be uploaded.
File download requests, with large files to be downloaded.
POST and GET requests containing exotic Unicode Encoding e.g. %2e%2e%5c etc.
POST and GET requests while performing intelligent fuzzing.
Enforcement of single SSL/TLS Handshake:
Not much to be said here. Simply enforce a single TLS handshake if the malicious payloads are going to consume more resources than the handshake it self. This will cause the server to consume resources.
Note: Such type of an attack can also be used to as a diversion to hide other type of attacks, such as SQLi etc.
The diagram below demonstrates where potentially system is going to crash first:
Other Uses of The This Tech
We can use this knowledge to perform the following tasks:
Optimize Web App Scans
Optimize directory enumeration
Optimize online password cracking on Web Forms
Optimize manual SQLi attacks
Useful Tools
There are some tools out there that make use some of the principles mentioned here:
Turbo Intruder - https://github.com/PortSwigger/turbo-intruder - Turbo Intruder is a Burp Suite extension for sending large numbers of HTTP requests and analyzing the results. It's intended to complement Burp Intruder by handling attacks that require exceptional speed, duration, or complexity.
Skipfish - https://code.google.com/archive/p/skipfish/ - Skipfish is an active web application security reconnaissance tool. It prepares an interactive sitemap for the targeted site by carrying out a recursive crawl and dictionary-based probes.
Countermeasures
Things to do to avoid this type of attacks are:
Firewall HTTP state filtering rules
Firewall HTTPS state filtering rules
Firewall HTTP/2 blockage - Although not recommended
This post is going to explain how to test a Denial of Service Vulnerability without crashing the actual service. More specifically we will focus on two vulnerabilities a) the slowris vulnerability (also known as Apache Partial HTTP Request Denial of Service Vulnerability) and b) the TLS Renegotiation and Denial of Service Attacks.
Apache Partial HTTP Request Denial of Service Vulnerability
The target application Apache Server is vulnerable to a denial of service named Slow-DoS attack, due to holding a connection open for partial HTTP requests. Both Apache Versions 1.x and 2.x are vulnerable. Slow HTTP attacks are denial-of-service (DoS) attacks in which the attacker sends HTTP requests in pieces slowly, one at a time to a Web server. If an HTTP request is not complete, or if the transfer rate is very low, the server keeps its resources busy waiting for the rest of the data. When the server’s concurrent connection pool reaches its maximum, this creates a DoS. Slow HTTP attacks are easy to execute because they require only minimal resources from the attacker.
Business Impact
A remote attacker can cause a denial of service against the Web server which would prevent legitimate users from accessing the site.
Remediation
There are no vendor-supplied patches available at this time. Upgrade to the latest version.
Welcome
to Slowloris - the low bandwidth, yet greedy and poisonous HTTP client
Multithreading enabled.
Connecting
to xxx.xxx.xxx:80 every 2000 seconds with 100 sockets:
Building sockets.
Building sockets.
Sending data.
Current
stats: Slowloris has now sent 446
packets successfully.
This thread now sleeping for 2000 seconds...
Sending data.
Current
stats: Slowloris has now sent 500
packets successfully.
This thread now sleeping for 2000 seconds...
Hping3 output
hping3 -T -p 80 xxx.xxx.xxx HPING xxx.xxx.xxx (eth1 xxx.xxx.xxx): NO FLAGS are set, 40 headers + 0 data bytes hop=1 TTL 0 during transit from ip=xxx.xxx.xx. name=xxx hop=1 hoprtt=0.6 ms ...[omitted]... --- 192.168.0.2 hping statistic --- 10 packets transmitted, 21 packets received, 0% packet loss
Explanation
In this scenario we send a low bust of packages using Slowloris and then launched Hping3 in port 80 (the same port as Slowloris) and saw that because the Slowloris open too many connections start receiving more packages than send.
TLS protocol is prone to a security vulnerability that allows for man-in-the-middle attacks and Denial of Service attacks. This issue does not allow attackers to decrypt encrypted data. More specifically, the issue exists in a way applications handle the session renegotiation process and may allow attackers to inject arbitrary plaintext into the beginning of application protocol stream.
In case of the HTTP protocol used with the vulnerable TLS implementation, this attack is carried out by intercepting 'Client Hello' requests and then forcing session renegotiation. An unauthorized attacker can then cause the webserver to process arbitrary requests that would otherwise require valid client side certificate for authorization. The attacker will not be able to gain direct access to the server response.
Denial of Service attack is also be feasible. This attack further exploits the SSL secure Renegotiation feature to trigger thousands of renegotiation via single TCP connection and crush the service.
Business Impact
An adversary can potentially exploit the vulnerability and cause compromise of the confidentiality and availability of the vulnerable service.
Remediation
Man In The Middle Attack:
OpenSSL workaround- OpenSSL has provided a version (0.9.8l) that has a workaround. Please refer to OpenSSL Change Log (Changes between 0.9.8k and 0.9.8l Section).
Microsoft workaround - Enable SSLAlwaysNegoClientCert on IIS 6 and above: Web servers running IIS 6 and later that are affected because they require mutual authentication by requesting a client certificate, can be hardened by enabling the SSLAlwaysNegoClientCert setting. This will cause IIS to prompt the client for a certificate upon the initial connection, and does not require a server-initiated renegotiation.
For Denial of Service Attack – No real solutions exists. The following steps can mitigate (but not solve) the problem:
Disable SSL-Renegotiation
Install SSL Accelerator
Example
host:xxx.xxx.xxx
Handshakes 0 [0.00 h/s], 1 Conn,
0 Err
Handshakes 44 [43.48 h/s], 16 Conn, 0 Err
Handshakes 118 [71.32 h/s], 25 Conn, 0 Err
Handshakes 193 [76.69 h/s], 32 Conn, 0 Err
Handshakes 290 [99.53 h/s], 38 Conn, 0 Err
Handshakes 371 [79.16 h/s], 43 Conn, 0 Err
Handshakes 459 [89.97 h/s], 48 Conn, 0 Err
Handshakes 545 [87.55 h/s], 52 Conn, 0 Err
Handshakes 632 [84.57 h/s], 56 Conn, 0 Err
Handshakes 728 [96.96 h/s], 60 Conn, 0 Err
Handshakes 819 [91.05 h/s], 63 Conn, 0 Err
Handshakes 913 [95.76 h/s], 66 Conn, 0 Err
Handshakes 989 [76.02 h/s], 70 Conn, 0 Err
Handshakes 1086 [96.98 h/s], 73 Conn, 0 Err
Handshakes 1165 [78.37 h/s], 77 Conn, 0 Err
Handshakes 1264 [97.87 h/s], 81 Conn, 0 Err
…[omitted]…
Handshakes 3642 [89.20 h/s], 144 Conn, 0 Err
Handshakes 3738 [92.35 h/s], 146 Conn, 0 Err
Handshakes 3828 [92.36 h/s], 148 Conn, 0 Err
Handshakes 3919 [93.75 h/s], 149 Conn, 0 Err
Handshakes 4003 [83.73 h/s], 151 Conn, 0 Err
Handshakes 4099 [90.18 h/s], 153 Conn, 0 Err
Handshakes 4197 [105.10 h/s], 155 Conn, 0 Err
Handshakes 4288 [90.83 h/s], 157 Conn, 0 Err
Handshakes 4379 [88.02 h/s], 159 Conn, 0 Err
Handshakes 4468 [88.77 h/s], 160 Conn, 0 Err
Handshakes 4568 [95.30 h/s], 162 Conn, 0 Err
Handshakes 4649 [87.94 h/s], 164 Conn, 0 Err
Handshakes 4743 [89.97 h/s], 166 Conn, 0 Err
Handshakes 4844 [106.67 h/s], 167 Conn, 0 Err
Handshakes 4930 [81.71 h/s], 169
Conn, 0 Err
Hping3 output
hping3 -T -p 443 xxx.xxx.xxx HPING xxx.xxx.xxx (eth1 xxx.xxx.xxx): NO FLAGS are set, 40 headers + 0 data bytes hop=1 TTL 0 during transit from ip=xxx.xxx.xx. name=xxx hop=1 hoprtt=0.6 ms ...[omitted]... --- xxx.xxx.xxx hping statistic --- 10 packets transmitted, 15 packets received, 0% packet loss Conclusion
Running point and click hacking tools for testing for Symmetric DoS vulnerabilities should not be a taboo. If this is done then there zero doubt that this specific vulnerability can be exploited e.g. the sys admin can use stress test tools to record the performance of the server etc.