 Ja und damit herzlich willkommen auf deutschen Übersetzungen vom Talk Identifikation von multi binary schwachstellen in embedded firmware im großen maßstab live vom 36.chauskommunikation kongress in leipzig Eure Übersetzer für diesen tags sind eipern und tribut wir freuen euch uns über eure rückmeldungen gerne auf twitter mit dem hashtag c3t Ja danke für die einführung. Hallo. Mein name ist Nino. Ich werde heute meine arbeit vorstellen Karonte also Identifikation von multibinary Schwachstellen in embedded firmware in großen maßstab. Das ist eine zusammenarbeit von mir mit meinen kollegen bei der Universität Sondababara und der asu Also bevor es losgeht schauen wir uns mal an was iot devices also internet der dingegeräte so sind Wir haben jetzt gerade erst die 20 milliarden marke werden wir erreichen und in einer studie wurden es bei 16 millionen haushalten wurden gefunden das 70 prozent der Wohnungen in nordamerika ein iot device haben Die machen das tägliche leben smarter kann mit alexa reden der interagiert dann mit einem thermostat und macht die temperatur im raum Wie man das möchte üblicherweise funktioniert das über smartphones man schickt eine anfrage über das lokale netzwerk an den tür das türschloss oder man benutzt einen cloud endpunkt also der von einer dem hersteller verwaltet wird oder man benutzt einen iot hub das heißt das smartphone sendet eine anfrage an den hub und der leitet es dann weiter an die iot geräte und wie man sich vorstellen kann sind diese iot geräte werden also sammeln daten und manche sind sensitiver und manche eben nicht so empfindlich und überlegt euch den unterschied zwischen ist das licht angeschaltet oder den daten die eine sicherheitskamera einsammelt und entsprechend kann ein solches gerät auch Sicherheit und privatsphäre gefährden also die implementierung eines smarten türschlosses oder die bremsen deines smarten autos also die frage ist sind iot geräte sicher und näher wie alles andere natürlich sind sie es nicht also in 2016 hat das mirai botnetz Millionen von iot geräten kompromittiert und benutzt um Internetdienste zu unterbrechen github und netflix zum beispiel und in 2018 wurden 154 schwachstellen in iot geräten veröffentlicht das sind 15 prozent im vergleich zu 2017 mehr also ist die frage wie soll es denn jetzt so schwierig iot geräte sicher zu machen ja also wie werden die gebaut und wie werden sie gemacht und wenn man das plastik Entfernt dann sehen die iot geräte üblicherweise so aus das ist eine platine mit einigen chips drauf man kann normalerweise den haupt chip den mikrocontroller und ein oder mehr peripherie controller die mit externen geräten interagieren also zum beispiel die des schloss an dem smarten türschloss oder die kamera Die das design ist relativ generisch aber die implementierungen sind sehr unterschiedlich also zum beispiel gibt es Viele verschiedene architekturen mit x86 power pc und so weiter und manchmal sind die auch sogar proprät her das heißt Als jemand der sicherheit da analysiert hat ein großes problem dabei die sicherheit der firmware zu analysieren wenn er die hersteller spezifik hat nicht kennt und Die werden auch in umgebungen ausgeführt die sehr eingeschränkte umgebungen haben das heißt sie haben sehr speziell optimierten code und die hersteller führen da dinge aus die sehr optimiert sind und iot geräte Benutzen auch externe geräte also sowas wie kamera Sensoren und so weiter die auch wieder Speziellen code ausführen und diese firmware auf IOT geräten ist entweder linux basiert oder software die nur als binär daten vorlegen und linux basiert ist der übliche fall Das 86 prozent der firmware basiert auf linux und bei blobs also bei binär daten Es ist dann meistens das opera das betriebssystem und die benutzer Applikationen in einem großen binär paket zusammengepackt sagen wir man sendet ein Anfrage von seinem smart form an den web server dann Ist es eine binary auf der firmware Dann wird es gepasst und dann wird das wahrscheinlich an der weitere binary weitergegeben Den händler der sich darum kümmert der gibt eine antwort zurück Der web server schaut sich das an und generiert daraus eine antwort an das smartphone Sind wir wieder zurück bei der frage warum ist es schwer iot geräte zu Sicher zu machen Es gibt natürlich viele Arbeiten die sagen wie man sowas analysieren kann als zum beispiel statische analysen und Ganz viele andere arbeiten die am ende dich am ende noch mal kurz vorstellen werde Natürlich Haben diese ansätze alle ein bisschen probleme Dynamische analysen ist sehr schwer Auf groß maßstäben anzuwenden weil sie sehr sehr sehr eigene Umgebung haben aber statische analysen ist auch schwer weil es zu viele Viele false positives haben das heißt wenn wenn man die dann einzeln Analysiert dann gibt es viel zu viele false positives Zum beispiel wenn wir jetzt hier unsere beiden binaries haben das tatsächlich dieses beispiel ist hier gefunden haben Hier sehen wir den web server den user Request nimmt dann packt er das in der environment variable und dann wird das in der händler binary ausgeführt Dann sehen wir hier ist ein Wenn hier eine anfreie rennen kommt dann wird es geschaut ob da was bestimmtes drin ist oder ob es zu lang ist und ja dann wird einfach nichts gemacht und Hier der händler nimmt das jetzt aus der aus der environment und Das ist halt nicht komplett user kontrolliert diese Diese variablen und dann gibt es hier diese Diese binary kopiert jetzt diese strings aus dem environment Die bloß 128 byte lang sind also in ein buffer der bloß 128 byte groß ist und das könnte jetzt hier in bug sein aber das zweite nicht weil wir denken das kommt vom Vorm system das kriegt das hin das zu behandeln links Nennen wir das die setter binary weil es die daten nimmt und weiter gibt und Das andere nennen wir die getter binary weil es die daten konsumiert Das die aktuellen bugsucht tools sind dafür nicht so gut Weil sie Schauen sich mal bis eine binary an und dann gibt es entweder nicht alle bugs Wenn der web server bloß analysiert wird oder viele false positives wenn der getter analysiert wird so wie kommunizieren diese kommunizieren wie kommunizieren diese prozess eigentlich zum Beispiel Interprozesskommunikation zum Beispiel über daten oder Memory mapped i o oder so weiter Es wird meist über irgendwelche Schlüssel weitergegeben zum Beispiel über eine query string environment variablen Jede binary die solche geteilte daten verwaltet muss wissen wo die daten verfügbar sind zum Beispiel in der environment variable oder so und das sorgt dafür dass die daten meist einfach in der binary zu finden sind Um diese bugs jetzt zu finden müssen wir schauen wie die user daten durch die binaries geschoben werden und weitergegeben werden Ja und damit kommen wir jetzt zu der eigenen eigentlichen arbeit also wir definieren erstmal das bedrohungsmodell wir sagen ein angreifer schickt beliebige anfragen über das netzwerk sowohl über das lokale netz als auch über das internet zur iot gerät und üblicherweise Haben auch die geräte die über die cloud kommunizieren irgendeine art von lokaler kommunikation Und unsere forschung zeigt dass die meisten dieser geräte auch lokale kommunikationen haben und karonte ist ein statisches analyse tool dass den daten flow nachvollzieht Über verschiedene binäherdaten also einem ersten schritt findet in einem ersten schritt findet karonte die binaries die daten in die firmware hineinbringen so genannten border binaries also die grenz binäherdaten und dann verfolgt es wie die daten geteilt werden mit anderen binäherdaten binärdatein also zum beispiel wieder web server mit dem getter binary zusammenarbeitet also in dem stellt es da in einem bdg also in dem binary dependency graph nennen wir das also binäherdaten abhängigkeitsgraf und dann detektiert schwachstellen die von dieser von der falschen behandlung dieser daten resultieren also eine übersicht wir haben eine gepackte firmware wir packen die aus wir finden diese border binaries diese grenz binäherdaten wir bauen den grafen auf da sind cpfs notwendig das steht für communication paradigm finder also aufspürer für kommunikations paradigmen und dann wird das weitergegeben an das modul der daten flussanalyse und letztendlich wird das analysiert und daraus werden alarme generiert und das ist komplett statisch und basiert auf dieser statischen Analyse also zunächst müssen wir daten im netzwerk empfangen und dann also wir sagen grenz binäherdaten border binaries sind alle diese daten die daten sind alle daten die daten vom netzwerk empfangen und die dann parser enthalten um diese daten zu bearbeiten das heißt wir müssen erst mal diese parser finden und um diese parser zu finden benutzen wir andere arbeitet die eine par metrik benutzt um das zu zu finden diese da geht es um die anzahl der basic blocks die anzahl der speicher vergleichs operationen und die anzahl der sprünge und wenn ein datei daten vom vom netzwerk nimmt dann definieren wir hier auch noch zwei weitere metriken also zum einmal ob netzwerk schlüsselwörter vorhanden sind sowas wie htdp und und dann gibt es auch noch die die frage ob funktionen benutzt werden wie wie lesen vom socket und dann kommen wir hier auf eine parsing score also auf ein eine zahle die einfach nur eine summe ist und umso höher die das das binary also wir schauen uns quasi also wir ermitteln für jedes binary diese diese zahl und dann schauen wir uns die an die die diesen höchsten score erreichen wir schauen uns hier den cluster an mit den binehrdateien die die diesen höchsten werte erreicht haben und danach bauen wir den abhängigkeits graf ab der bildet ab wie die dateien voneinander abhängig sind also in dem fall in dem einfachen graf sehen wir das a mit c kommuniziert über eine datei und die selbe datei kommuniziert mit einem anderen mit einer anderen datei b über umgebungsvariablen also schauen wir uns mal an wie das funktioniert also wir starten mit dem identifizierten grenz binehrdateien und dann schauen wir uns die schlüsselwörter an die wir gefunden haben und wir analysieren ob das die binehrdatei auf irgendein ipc also einen kommunikations paradigma aufbaut um die daten zu teilen und dann schauen wir ob es die daten setzt oder ob es die daten bekommt und dann suchen wir nach dem schlüssel also zum beispiel der namen der umgebungsvariablen und dann suchen wir nach der bei der firmware nach anderen binehrdateien die auch den selben schlüssel möglicherweise benutzen und planen die auch mit zu analysieren und diese kommunikationsparadigmen die werden erkannt über eine module die cpf heißen und die diese cpf werden benutzt um die daten schlüssel in den firmware es auch zu finden und es gibt mit karonte gibt es cpf eine ganze menge von schlüsseln die wo der der kommunikationsmechanismus unbekannt ist und die idee bei diesem generischen cpf den wir den semanthischen cpf nennen ist dass datenschlüssel als index benutzt werden mussten auf eine gewisse menge als auf auf daten in diesem einfachen beispiel also schauen wir uns mal an wie dieser algorithmus funktioniert wir fangen mit dem grenz binary an mit der datai und hier wird jetzt wieder die uri gepasst hier unten jetzt sehen wir hier oben es wird ein string compare ausgeführt über ein netzwerk keyword und das heißt wir nehmen jetzt die variable p und markieren sie und die wird hier von der funktion zurückgegeben von diesen zwei verschiedenen punkten und jetzt machen wir weiter wir sehen das data markiert wird und das wird der funktion zn weitergegeben das heißt die umgebungs cpf wird jetzt verstehen dass markierte daten eine umgebungsvariable übergeben werden und damit ist dieses dieses binary ist der setter also der die daten setzt und dann markieren wir den den schlüssel query string und suchen in anderen binär daten nach nach diesem string die auch darauf abhängen und dann finden wir da drüben dieses diese binär datai und die hängt auch davon von dem query string ab und dann machen wir mit diesem binary weiter und dann schauen wir bauen wir daraus in sein grafen mit dem wir den daten vorsehen dann auf diesem grafen sehen wir wie die daten limitiert werden also was für gesetzen sie entsprechen müssen gegeben vom setzer und kriegen so die regeln für den getter wir sagen hier bloß dass es die geringst möglichen limits weiterzugeben damit wir vielleicht wachs finden können z.B. haben wir hier links kriegen wir data was in query string variabel gesetzt wird das erste mal ist es an constrained und im zweiten fall ist es maximal hundert achts uns zu sich beit und weil wir bloß die weniger schwachen voraussetzungen weitergeben es ist immer noch unkonstruent für uns hier bei der getter binary bekommen wir die variabel aus dem environment und das hier dann unkonstruent und dann schauen wir uns an ob ob daten irgendwelche an irgendwelchen orten ankommen können die wo sie auf unsicherheit und weise weiter verarbeitet werden das ist z.B. mem copy ähnliche funktionen und ein paar andere und dann schauen wir uns noch mal das beispiel an hier unsere query ist vom user und es ist nicht limitiert irgendwie und dann sehen wir hier ein struck copy was von unserem query kommt und arg ist auch bloß 128 byte groß das heißt wir kriegen hier eine warnung unsere engine die das macht ist basiert auf bootstump und es macht es führt symbolisch aus das heißt zum beispiel sehen wir hier hier gibt es erstmal t y was es von irgendein input nimmt die von der seed funktion da stellen wir dann jetzt eine symbolisch variabel t y die die nennen wir jetzt taint also die die nennen wir dann taint also dass sie vom user beeinflussbar ist und dann folgen wir dem datenlos weiter dann wird x taint t y plus 5 und das heißt wir haben immer noch irgendwelche Irgendwann kenne sie immer noch als user beeinflusst aber wenn sie jetzt irgendwelche anderen werte zu gewiesen bekommt dann sagen wir es nicht mehr vom user beeinflusst vom user beeinflusst nehmen wir auch weg sobald es irgendwie die daten limitiert werden zusätzlich haben wir noch zwei weitere Sachen zugefügt zum beispiel sagen wir wie betrachten wir den fahrt der genommen wird und Was für abhängigkeit es gibt zum beispiel wenn wir jetzt hier unseren Unser destination haben die von irgendeinem Funktionen kriegen und user input dann haben wir ein fahrstfunktion Dann gibt es hier quasi unendlich viele symbolische fahrte und nur in einem fahrt wir In einem fahrt Return wir user data und jetzt prioritisieren wir das Auf einer art und weise und Dann prioritisieren wir diesen fahrt vor andern falls man da user control to data Ja bei dieser art und weise können wir also auf kluge art und weise erkennen ob daten Von nutzer kommen oder nicht also ob wir die markieren müssen und die werden Wenn wir hier unten zum beispiel schauen Hier wird die länge des strings command gelesen und wenn sie länger ist als 512 dann wird minus eins zurück gibt und ansonsten wird kopiert das heißt wenn wir jetzt string Längen nicht analysieren zum beispiel weil die ana weil die statische analyse das nicht kann dann Ist möglicherweise der die markierung von von command anders als die markierung von n und dieses diese Dieses dieses string copy hier unten kann dann zu einem false positive führen also zu einem alarm obwohl es eigentlich keiner sein sollte das diese diese Das erzeugt ja eine abhängigkeit zwischen der markierung von command und n und Hier haben wir im zwem fall die Wird auch n mit markiert diese prozedur ist automatisch wir finden also möglicherweise Kot der equivalent ist zu string length und dann haben wir finden wir kot der diese abhängigkeiten erzeugt also schauen wir uns das mal an wir haben jetzt Schauen wir uns drei verschiedene Auswertungen angeschaut auf verschiedenen datensets das neueste ist 53 filmwärtsbeispiele von sieben verschiedenen herstellern und das zweite sind 899 filmwärts die wir Aus anderen arbeiten gefunden haben hier sehen wir die gesamtzahl der baineries die wir uns angeschaut haben 8500 und unser system hat 87 erzeugt wobei 51 echte Problemen waren und 34 davon waren multibinary schwachstellen also schwachstellen die wir gefunden haben indem wir den daten fluss zwischen den verschiedenen binärdateien angeschaut haben und dann gibt es auch eine vergleichende Auswertung das heißt wir haben versucht Verschiedene strategien anzuschauen in der ersten strategie da sehen wir jedes binärdatei Unabhängig und haben dann quasi für jede filmwärts bis zu sieben tagelang die analyse laufen lassen Da hat das system fast 21.000 alarme generiert Wobei wir nur 200 binärdateien betrachtet haben und im zweiten beispiel haben wir die Pasa angeschaut und nur die pauser und da hat das system 9300 alarme erzeugt Wobei wir jetzt nicht wissen in diesem beispiel wie der benutzer input Reinkommt und deswegen haben wir quasi jeden Prozesskommunikation also alles was in das binary reinkommt als benutzer generiert betrachtet und dann gucken wir die binaries einzeln an also wir Schicken die einschränkungen nicht weiter und das hat fast 13.000 alarme erzeugt und die letzte Variante ist dann wir benutzen karonte und hier gab es jetzt eben nur sieben und vier vier 74 alarme okay und dann haben wir uns hier dieses große auswertung angeschaut und fast 40 prozent der Dieser dieser beispiele waren multibinaries also es werden mehrere binärdateien Beteiligt und dieses system hat jetzt 1.000 alarme erzeugt in dieser diese tabelle ist sehr Ausführlich ich schomme die detail sind in den paper wir haben also festgestellt dass eine durchschnittsfirma 4 grenz binärdateien hatte und ein bdg 5 binaries enthält und manche haben mehr als 10 Wir haben jetzt angeschaut für die performance 80 prozent der firmware wurde in einem tag analysiert das ist die des bildlings oben aber es gab eine große abweichung das lag dann an implementierungsdateien zum beispiel enger das braucht Länger als sieben stunden um einige bfgs zu erzeugen und manche haben eine sehr große zahl von datenschlüsseln und der die anzahl von fade das sieht man an dem zweiten bild von oben dass Die anzahl der fade kein kein einfluss hat auf die zeit und die anderen bilder dass die performance nicht heftig davon abhängt von der grüße der firmware Damit meinen wir die anzahl der binaries in einem in so einem auswertung sample und die anzahl der blocks basic blocks Also wie führt man karonte aus es ist eigentlich relativ einfach man braucht eine firmware die man analysieren will man erzeugt eine Konfiguration statei und dann führt man es aus also schauen wir uns das mal an Hier ist ein beispiel für eine konfiguration statei das hat nur ganz wenige informationen Die meisten sind auch optional die einzigen die nicht sind ist der fahrt Fff fahrt also fahrt zur firmware und das hier die architektur und Base address wenn die firmware ein block ist ein binär block die anderen filter sind alle optional Und man kann die ein einsetzen wenn man informationen über die firmware hat Diese dokumentation für diese fälder die findet ihr alle bei uns auf github und wenn man das mal Gesetzt hat dann kann man karonte ausführen Wie das funktioniert also wie gesagt das link den link zu unserem github reto Seht ihr dann gleich ich werde es jetzt nicht ausführen Aber das einzige was ihr machen müsst ist das hier ausführen Es wird also quasi nur auf das konfiguration statei ausgeführt es wird jetzt jeden schritt ausführen Den ihr gesehen habt das wird jetzt ein paar stunden dauern deswegen brecht es ab und am ende wird es ein Resultatdatei erzeugen die sieht dann so aus da passt sind jetzt eine ganze menge sachen zu sehen ich werde nur ganz wichtige sachen jetzt hervorheben Und eins was ihr sehen könnt ist das Die border binaries also die grenz binäre teilen die identifiziert wurden Weiß jetzt nicht wie viele es hier sind Solange es Keine keine false negatives gibt also welche nicht detektiert werden ist das alles super Kann sein dass ich was entfernt habe ach ja hier hier in dem fall ist htdp d ein Ein ein treffer der web server den wir vorher genannt haben und dann haben wir den bdg also den grafen in dem fall hat Karonte gefunden das htdp d mit zwei verschiedenen Dateien kommuniziert nämlich file access punkt cgi und cgi bin und dann haben wir Informationen über diese cpfs man kann zum beispiel hier sehen dass Hier kann man zum beispiel sehen dass htdp d 28 datenschlüssel hat Und die der semanische cpf hat 27 gefunden und das muss auch woanders noch eingeben den sehe ich gerade nicht aber was auch immer Und dann haben wir eine liste von alarmen manche sind möglicherweise doppelt Man kann da jetzt auch reingehen und die alle manuell sich angucken aber ich habe ein kleines utility geschrieben ein werkzeug dass die ganzen Schleifen rausfiltert muss mal gucken wie ich es genannt habe Der hier vielleicht ja und jetzt kann man sehen im summe hat das system jetzt Acht Alarm erzeugt schauen wir uns mal einen an und ich habe jetzt auch erst Neulich festgestellt dass der fahrt der Hier angezeigt wird nicht der fahrt vom getter binary ist Sondern nur bis zur senke das werde ich jetzt noch reparieren dass und in den ganzen fahrt dann hier auch mit anzeigen Der key content type hat benutzer input und das wird an die senke an dieser adresse unsicher übergeben und dass die binärdata heißt file access punkt cgi Und wir können mal gucken was da passiert und da sieht man jetzt an dieser stelle haben wir ein string copy dass den inhalt von also die die Inhalt von hasteg nach destination kopiert und das kommt von hasteg kommt von diesem getelf aufruf und destination kommt als parameter für diese funktion und wenn wir und der der buffer ist Neulich 60 bytes groß das ist also ein echter treffer Okay, also zusammenfassend wir haben jetzt hier eine strategie vorgestellt um datenfluss zwischen verschiedenen binaries nachzufolgen Wir haben das auf 952 firmware Firmware Beispielen ausprobiert und Firmwareanalyse ist nicht einfacher einfacher und Schwachstellen gibt es weiterhin Firmware besteht aus vielen verbundenen komponenten und statische analyse kann man benutzen um Auf große maßstab diese schwachstellen zu finden und Kommunikation ist wichtig um die präzision zu beizubehalten hier sind die quellen für meine präsentation und jetzt Könnt ihr gerne fragen stellen Vielen Dank für den tollen vortrag Hier haben wir drei mikrofoner Bitte geht zu den mikrofonen Mikrofon 2 Schaust du dir die Imports von libc an Oder geht es auch mit statisch gelinken binaries Oder ist das alles sementisch Also Wenn wir zum Beispiel Enger anschauen Dann wird rausgesucht um wie was das ziel ist wenn man die libc irgendwie ein paar cpfs benutzen die libc Environment cpu zum cpf benutzt zum beispiel die libc Aber auch das sementische cpf was also zum beispiel es gibt sowas nicht wie libc oder manche Händler haben ihre eigenen funktionen neu implementiert Zum beispiel wenn jemand ein eigenes zpf programmiert hat In kleinen environments gibt es da auch getter die über dma direkten memory zugriff benutzen für interprozesskommunikation Schaut sie es auch an Wie kriegt man das unterschieden von dem normalen ipc Also wenn ich das richtig verstehe dann Wird jetzt quasi mmio Gefragt wo also Daten von beliebigem Speicher gelesen und was wir festgestellt haben ist dass die adressen für diese daten Irgendwo hart kodiert werden das heißt der hersteller schreibt hin dieser prozess schreibt irgendwas nach adresse a und der andere liest es von da Und wenn wir irgendwo so eine adresse finden dann gehen wir davon aus das ist wahrscheinlich gelesen von irgendwelchen interessanten daten Wie unterscheidet ihr das Zwischen cpf und normal zu griffen über diese fixierten adressen Ja das ist genau was der sementische cpf tut Was ist die lizenz für caravante Du die Software lizenz ich habe im git repose geschaut da gibt es keiner Ja das ist eine gute frage ich habe mir da noch keine Gedanken gemacht ich werde das noch machen Gibt es noch fragen von hier oder aus dem internet Dann bitte eine große runde applaus und damit verabschieden wir uns aus der übersetzter kabine wir waren