Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
vbox_cve_2017_10235 — [CVE-2017-10235] Beschreibung und PoC des Pufferüberlaufs im VirtualBox E1000 Gerät | Kitploit
Tools/GitHubGitHub/fundacion-sadosky/vbox_cve_2017_10235
Embedded-System-SicherheitSchwachstellenanalyseExploitationFuzzingHardware-SicherheitBinary-Exploitation
GitHubfundacion-sadosky/vbox_cve_2017_10235

vbox_cve_2017_10235

[CVE-2017-10235] Beschreibung und PoC des Pufferüberlaufs im VirtualBox E1000 Gerät

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen
Repository anzeigen
36513vor 8 JahrenVon Kitploit geprüft

CVE-2017-10235: Pufferüberlauf im VirtualBox E1000-Gerät

Einleitung

Das folgende Dokument beschreibt einen Fehler in VirtualBox v5.1.22 (behoben in v5.1.24) in der Gastgeräte-Emulationskomponente DevE1000 (Intel 82540EM Ethernet Controller Emulation), in der Funktion e1kFallbackAddToFrame, der zu einem Pufferüberlauf im Host führt, wenn das Gast-Betriebssystem von einem Angreifer kontrolliert wird.

Der Fehler wurde von Oracle im CPU vom Juli 2017 mit der veröffentlichten CVE-2017-10235 bestätigt.

Die Schwachstelle wurde sowohl mit einem Linux- (Ubuntu 16.04) als auch einem Windows- (v8.1) Host, auf dem ein Linux-Gast (ebenfalls Ubuntu 16.04) ausgeführt wurde, bestätigt, aber die Schwachstelle könnte in vielen verschiedenen Host/Gast-Kombinationen ausgelöst werden. In allen Szenarien wird die Standard-Netzwerkkonfiguration angenommen: nur ein Netzwerkadapter verbunden mit NAT vom Typ Intel PRO/1000 MT Desktop (82540EM).

Da Kontrollstrukturen (einschließlich Funktionszeigern) mit vom Angreifer kontrollierten Daten überschrieben werden können, ist davon auszugehen, dass in vielen Szenarien eine entfernte Codeausführung (RCE) erreicht werden kann. Oracle hat diesem Fehler einen niedrigen CVSS-Score zugewiesen, da es davon ausging, dass er ein Kein Vertraulichkeitsrisiko und eine Niedrige Integrität aufweist, was nach unserer Einschätzung das vollständige Kompromittierungspotential dieses Fehlers nicht widerspiegelt (eine Erklärung für die Möglichkeit von RCE wird unten gegeben).

Fehlerbeschreibung und Ausnutzung

Der VirtualBox-Code, der die Emulation des [Intel 82540EM Ethernet Controllers][intel_manual] implementiert (in [src/VBox/Devices/Network/DevE1000.cpp][DevE1000_cpp]), in der Funktion [e1kFallbackAddToFrame][e1kFallbackAddToFrame], implementiert das Hardware-TCP-Segmenting:


static int e1kFallbackAddToFrame(PE1KSTATE pThis, E1KTXDESC *pDesc,
                                bool fOnWorkerThread)
{
#ifdef VBOX_STRICT
   PPDMSCATTERGATHER pTxSg = pThis->CTX_SUFF(pTxSg);
   Assert(e1kGetDescType(pDesc) == E1K_DTYP_DATA);
   Assert(pDesc->data.cmd.fTSE);
   Assert(!e1kXmitIsGsoBuf(pTxSg));
#endif

   uint16_t u16MaxPktLen = pThis->contextTSE.dw3.u8HDRLEN +
                           pThis->contextTSE.dw3.u16MSS;
   Assert(u16MaxPktLen != 0);
   Assert(u16MaxPktLen < E1K_MAX_TX_PKT_SIZE);

Diese Funktion prüft korrekt, dass die maximale TX-Paketlänge (u16MaxPktLen) unter dem Standardmaximum von 16288 Bytes (E1K_MAX_TX_PKT_SIZE) liegt, tut dies jedoch in Form eines Assert-Makros, das in einem Release-Build deaktiviert wird, wodurch die Prüfung für den Endbenutzer effektiv nutzlos wird. Dies kann mit der analogen Funktion [e1kAddToFrame][e1kAddToFrame] verglichen werden, die die Prüfung mit einem expliziten if anstelle des Assert durchsetzt:


static bool e1kAddToFrame(PE1KSTATE pThis, RTGCPHYS PhysAddr,
                         uint32_t cbFragment)
{
   PPDMSCATTERGATHER   pTxSg    = pThis->CTX_SUFF(pTxSg);
   bool const          fGso     = e1kXmitIsGsoBuf(pTxSg);
   uint32_t const      cbNewPkt = cbFragment + pThis->u16TxPktLen;

   if (RT_UNLIKELY( !fGso && cbNewPkt > E1K_MAX_TX_PKT_SIZE ))
   {
       E1kLog(("%s Transmit packet is too large: %u > %u(max)\n",
               pThis->szPrf, cbNewPkt, E1K_MAX_TX_PKT_SIZE));
       return false;
   }

Der Unterschied zwischen der Verwendung der normalen Funktion (e1kAddToFrame) und der Fallback-Funktion (e1kFallbackAddToFrame) wird in e1kXmitDesc() entschieden und hängt von zwei Faktoren ab: dass das TSE-Flag in den Daten/Kontext-Deskriptoren aktiviert ist (vom OS des Gast-Systems kontrolliert) und dass das GSO-Flag deaktiviert ist. Letzteres hängt von vielen Faktoren ab, daher gibt es viele Möglichkeiten, es zu deaktivieren, aber die bequemste ist, den Loopback-Modus zu aktivieren, der über das Receive Control Register (in den RCTL.LBM-Bits) konfiguriert wird, das ebenfalls vom Gast-OS kontrolliert wird.

Die Aktivierung des Loopback-Modus führt dazu, dass die Funktion [e1kXmitAllocBuf][e1kXmitAllocBuf] den aTxPacketFallback-Puffer (Transmit packet buffer use for TSE fallback and loopback) für die Allokation des PDM-Streugather-Puffers mit der genannten Länge von 16288 Bytes (E1K_MAX_TX_PKT_SIZE) verwendet und signalisiert, dass GSO deaktiviert wird (indem ein NULL in pvUser gesetzt wird).


if (RT_LIKELY(GET_BITS(RCTL, LBM) != RCTL_LBM_TCVR))
{

  ...

}
else
{
 /* Create a loopback using the fallback buffer and preallocated SG. */
 AssertCompileMemberSize(E1KSTATE, uTxFallback.Sg, 8 * sizeof(size_t));
 pSg = &pThis->uTxFallback.Sg;
 pSg->fFlags      = PDMSCATTERGATHER_FLAGS_MAGIC |
                    PDMSCATTERGATHER_FLAGS_OWNER_3;
 pSg->cbUsed      = 0;
 pSg->cbAvailable = 0;
 pSg->pvAllocator = pThis;
 pSg->pvUser      = NULL; /* No GSO here. */
 pSg->cSegs       = 1;
 pSg->aSegs[0].pvSeg = pThis->aTxPacketFallback;
 pSg->aSegs[0].cbSeg = sizeof(pThis->aTxPacketFallback);
}

Dies führt dazu, dass der Aufruf der Funktion e1kXmitIsGsoBuf (innerhalb von [e1kXmitDesc][e1kXmitDesc]) False zurückgibt und mit aktiviertem TSE im Daten-Deskriptor der Ausführungsfluss zu [e1kFallbackAddToFrame][e1kFallbackAddToFrame_call] geht (anstelle der sichereren Funktion e1kAddToFrame mit der korrekten Prüfung).


/*
 * Add the descriptor data to the frame.  If the frame is complete,
 * transmit it and reset the u16TxPktLen field.
 */
if (e1kXmitIsGsoBuf(pThis->CTX_SUFF(pTxSg)))
{

  ...

}
else if (!pDesc->data.cmd.fTSE)
{

  ...

}
else
{
    STAM_COUNTER_INC(&pThis->StatTxPathFallback);
    rc = e1kFallbackAddToFrame(pThis, pDesc, fOnWorkerThread);
}

Innerhalb von e1kFallbackAddToFrame kann bei deaktivierter Prüfung in einem Release-Build die MSS beliebig groß gesetzt werden (bis zu 64K minus HDRLEN), wodurch eine beliebig große DTALEN an [e1kFallbackAddSegment][e1kFallbackAddSegment_call] übergeben werden kann:


/*
* Carve out segments.
*/
int rc;
do
{
 /* Calculate how many bytes we have left in this TCP segment */
 uint32_t cb = u16MaxPktLen - pThis->u16TxPktLen;
 if (cb > pDesc->data.cmd.u20DTALEN)
 {
     /* This descriptor fits completely into current segment */
     cb = pDesc->data.cmd.u20DTALEN;
     rc = e1kFallbackAddSegment(pThis, pDesc->data.u64BufAddr, cb,
                 pDesc->data.cmd.fEOP /*fSend*/, fOnWorkerThread);

Die Funktion [e1kFallbackAddSegment][e1kFallbackAddSegment] verwendet diesen Wert (nun als Argument u16Len), um aus dem Gastspeicher in den Puffer aTxPacketFallback im Hostspeicher zu kopieren (durch PDMDevHlpPhysRead) ohne weitere Prüfungen dieser Länge, wodurch der Pufferüberlauf verursacht wird (eines Puffers mit einer Kapazität von 16288 Bytes mit einer Speichergröße von bis zu 64K).


static int e1kFallbackAddSegment(PE1KSTATE pThis, RTGCPHYS PhysAddr,
                   uint16_t u16Len, bool fSend, bool fOnWorkerThread)
{
    int rc = VINF_SUCCESS;
    /* TCP header being transmitted */
    struct E1kTcpHeader *pTcpHdr = (struct E1kTcpHeader *)
            (pThis->aTxPacketFallback + pThis->contextTSE.tu.u8CSS);
    /* IP header being transmitted */
    struct E1kIpHeader *pIpHdr = (struct E1kIpHeader *)
            (pThis->aTxPacketFallback + pThis->contextTSE.ip.u8CSS);

    E1kLog3(("%s e1kFallbackAddSegment: Length=%x, remaining payload=%x,
             header=%x, send=%RTbool\n", pThis->szPrf, u16Len,
             pThis->u32PayRemain, pThis->u16HdrRemain, fSend));
    Assert(pThis->u32PayRemain + pThis->u16HdrRemain > 0);

    PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), PhysAddr,
                      pThis->aTxPacketFallback + pThis->u16TxPktLen, u16Len);

Mögliches RCE

Tool herunterladen