Er is een methode gepubliceerd voor het omzeilen van systemen voor geïsoleerde uitvoering van code in Python, gebaseerd op een al lang bekende kwetsbaarheid die is ontdekt in Python 2.7, in 2012, en tot op heden niet is verholpen in Python 3. Deze kwetsbaarheid stelt gebruikers in staat om met speciaal samengestelde Python-code toegang te krijgen tot al geruimde geheugen (Use-After-Free) in CPython. Aanvankelijk werd aangenomen dat deze kwetsbaarheid geen veiligheidsrisico vormde en alleen in zeer zeldzame gevallen, doorgaans kunstmatig gecreëerd, kon leiden tot het onverwacht beëindigen van een script.
De beveiligingsonderzoeker met het pseudoniem kn32 raakte geïnteresseerd in het probleem en slaagde erin een werkende exploit te ontwikkelen die de mogelijkheid biedt om elke systeemopdracht uit te voeren zonder directe toegang tot methoden zoals os.system. De exploit is geïmplementeerd in pure Python en werkt zonder het importeren van externe bibliotheken of het installeren van een handler 'code.__new__'. Van de hooks wordt alleen 'builtin.__id__' gebruikt, wat meestal niet verboden is. Vanuit praktisch oogpunt kan de aangeboden code worden gebruikt om isolatiemechanismen in verschillende diensten en omgevingen te omzeilen (bijvoorbeeld in opleidingsomgevingen, online shells, ingebedde handlers, enz.) die de uitvoering van code in Python toestaan, maar de toegankelijke aanroepen beperken en geen toegang geven tot methoden zoals os.system.
De aangeboden code is een equivalent van de aanroep os.system, werkende door het benutten van een kwetsbaarheid in CPython. De exploit werkt met alle versies van Python 3 op systemen met een x86-64 architectuur en toont stabiele werking in Ubuntu 22.04, zelfs wanneer de beschermingsmodi PIE, RELRO en CET zijn ingeschakeld. Het werk bestaat uit het verkrijgen van informatie over het adres van een van de functies in de uitvoerbare code van CPython vanuit de Python-code. Op basis van dit adres wordt het basisadres van CPython in het geheugen en het adres van de functie system() in de geladen instantie van libc berekend. Uiteindelijk wordt er een directe sprong naar een specifiek adres van system geïnitieerd door de pointer van het eerste argument te substitueren met de string '/bin/sh'.

Bron: opennet.ru
