Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 07/08/20 in Posts

  1. 5 points
    E seo, doar nu va ganditi ca cineva isi face cont chiar pe rst sa intrebe de aer conditionat...
  2. 5 points
    Tu chiar vrei sa iei premiul de prostul forumului cu intrebarile astea. https://lmgtfy.com/?q=lock+symbol+beside+wifi
  3. 5 points
    Singura aplicabilitate vad eu sa fie ca la stuxnet cu centrala nucleara din iran. Atunci americanii vazusera ca iranienii foloseau xp si plcuri siemens, insa nu foloseau conexiuni la internet. Singura modalitate de infectare deci era usbul. Dar, na, lucrurile astea tin de spionaj international, nu vor targeta ei orice pulete, mai ales ca trebuie sa aiba acces fizic la reteaua lui. Mai multe detalii pe: https://en.m.wikipedia.org/wiki/Stuxnet
  4. 5 points
    https://malware.news/t/turn-your-usb-fan-to-a-pentesting-device-for-red-teaming-lucideus/32206
  5. 5 points
    Salut, intrebarea suna ciudat dar are sens. Tastatura sau alte device-uri vin cu propriul microcontroller care ruleaza cod. In principiu nu se poate face nimic, dar teoretic, daca ar fi un dispozitiv indeajuns de avansat si ar avea o procedura de update de firmare s-ar putea ajunge la asa ceva. Daca ar avea, de asemenea, ar trebui sa verifice integritatea firmware-ului la care se face update/upgrade pe baza unei semnaturi digitale. Se cunoaste faptul ca in sistemele de operare moderne (datorita arhitecturii procesoarelor) exista o separare de privilegii la nivel de "ring" unde ring0 = Kernel mode, sistemul de operare care are acces la toate resursele iar ring3 = usermode care e mult mai limitat. Dar se poate vede si altfel aceasta problema daca intram mai in adancime in problema: Cu alte cuvinte, exista de exemplu chiar si in procesor in firmware care permite executia codului assembler (in machine code) pe care il cunoastem. Se poate face update la el asa cum s-a intamplat cand au aparut vulnerabilitati in procesoare gen Specter sau Meltdown cand pentru fix a fost necesar update de microcode (firmware de procesor). Exact acelasi lucru se poate intampla si cu alte device-uri. De exemplu placi video. Sau BIOS. Sau mai stiu eu ce. Si ca sa rezum problema, daca un device e indeajuns de avansat incat sa aiba (doar ca exemplu) functionalitati gen firmware update, in teorie (si in practica daca e vulnerabil la asa ceva si nu verifica aceste firmware updates) se poate infecta si cand ajunge pe un alt device sa fie in continuare infectat. De asemenea, un antivirus de exemplu nu are ce sa faca. PS: Asta nu inseamna ca acel device infectat va putea lua controlul asupra calculatorului la care e conectat ulterior. Sistemul de operare prin functionalitati gen Plug & Play si standarde gen PCI Express, USB sau altele, permit doar un numar de actiuni si nu sa faca ceea ce doresc. Acel device infectat va fi limitat la device-ul in sine, nu s-ar putea existinde la alte device-uri sau la sistemul de operare (decat desigur, daca exista probleme de securitate in OS). Sper ca ajuta.
  6. 5 points
    Singurla solutie pentru energie electrica nelimitata (care si functioneaza ca am testat si folosesc asta de ani de zile) e asta:
  7. 4 points
  8. 4 points
  9. 4 points
    E genul de om care ar fi interesat sa cumpere un derulator de cd-uri sau o sabie cu luneta..
  10. 4 points
    Who should use this tool? TL;DR: Generate JPEG earth imagery from coordinates/location name with publicly available satellite data. This tool is for a sentient being who wants to view high-res satellite imagery of earth, without digging through all the nitty gritty geospatial details of it. So if this is your first time trying to explore how parts of the Earth look from space, you're at the right place. NB: felicette at the present state searches for cloud-cover < 10%, and doesn't constrain results on the basis of dates. One can see Product Roadmap for upcoming features. Installation felicette depends on GDAL. But the following steps cover GDAL's installation as well. rio-color uses numpy headers to setup, thus installing numpy and GDAL=={ogrinfo --version} would be sufficient before installing felicette. Debian $ sudo add-apt-repository ppa:ubuntugis/ppa $ sudo apt-get update $ sudo apt-get install python-numpy gdal-bin libgdal-dev $ gdal-config --version <version-number> * activate virtual environment * $ pip install numpy GDAL==<version-number> $ pip install felicette MacOS $ brew install gdal $ gdal-config --version <version-number> * activate virtual environment * $ pip install numpy GDAL==<version-number> $ pip install felicette Docker As pointed out here, the following docker image works and is volume-mapped to the present working directory. Thanks @milhouse1337 for the docker-image. rio-color, one of the felicette's dependencies isn't available on conda ecosystem yet. Here's the link to a small discussion on an installation-issue. This section would be updated when there is a stable version of felicette for Windows. Felicette has plans to build in-house RGB image enhancement algorithms or use imagemagick /[similar tools on conda-forge] for a Windows release, at least until rio-color is available on conda-forge/conda. Usage To use it: $ felicette --help Usage: felicette [OPTIONS] Satellite imagery for dummies. Options: -c, --coordinates FLOAT... Coordinates in (lon, lat) format. This overrides -l command -l, --location-name TEXT Location name in string format -p, --pan-enhancement Enhance image with panchromatic band -pre, --preview-image Preview pre-processed low resolution RGB satellite image. -v, --vegetation Show Color Infrared image to highlight vegetation --help Show this message and exit. Felicette can download and process Landsat images taking the location's input as (lon, lat) or the location name. They can be used in the following way. With location name: $ felicette -l "Kanyakumari" With coordinates: $ felicette -c 77.5385 8.0883 -p option uses the panchromatic band to enhance image's resolution to 15 meters, contrary to resolution of RGB bands(30 meters). To get a better image using felicette use: $ felicette -p -c 77.5385 8.0883 -pre option downloads a low-res image for preview, to check if the image is worth your computation, Network I/O. $ felicette -pre -p -c 77.5385 8.0883 -v option generates a CIR image to highlight vegetation in 'red' color. Note that, '-p' option isn't taken into consideration while generating CIR imagery in felicette. $ felicette -pre -v -l "Kanyakumari" History Félicette was the first cat launched into space, on 18 October 1963. Even though she landed back on earth safely, Félicette was euthanized two months after the launch so that scientists could perform a necropsy to examine her brain. She was the only cat to have survived spaceflight. Here's a footage of the mission from the archives. When you get a satellite imagery using this tool, imagine Félicette took the picture for you : Preview and examples Here are some more sample images generated by felicette. Here is a link to the original images generated with RGB, CIR options. Following is a recording of the terminal session recording usage of felicette. https://asciinema.org/a/349495 Source
  11. 4 points
    Eu am vazut un caz similar in sisteme embedded: - stick USB normal, nou, fara nicio problema era introdus intr-un sistem, iar atunci cand se facea scrierea pe el erau afectate anumite block-uri (nu stiu exact cum si in ce fel); - daca introduceai acel stick USB cu date corupte in acelasi sistem sau intr-un alt sistem de acelasi tip genera un kernel panic instant, adica sistemul isi dadea reboot in loop cat timp era stick-ul conectat. Isi revenea doar dupa ce faceai remove la stick. Nu erau fisiere de update ci fisiere multimedia pe stick-ul respectiv. Tin minte ca problema era la un codec, la o metoda prin care se extrageau informatii dintr-un fisier video.
  12. 4 points
  13. 4 points
    Daca nu te informeaza ca te inregistreaza nu pot folosi acea inregistrare in caz de reclamatii, confirmare, judecata sau orice alta situatie. La fel cum nici tu nu o poti folosi daca nu anunti, cel putin ANPC asta mi-a comunicat cand am avut o situatie cu emag si le-am zis ca am inregistrarea apelului. Eu personal inregistrez toate apelurile, aparent pe Huawei e o functie din telefon fara batai de cap ce functioneaza mereu. Cand nu aveam timp/chef de vorba o aruncam pe asta cu apel inregistrat si inchideau, insa in ultima perioada vad ca nu mai inchid apelul asa multi si intr-un fel ma bucur. Am sesizat insa altceva, mai nou cand te suna cineva din callcenter nu iti mai zice robotul treaba cu inregistratul. Se prezinta persoana si iti zice ce vrea sa iti vanda/modifice si apoi iti arunca treaba cu apelul inregistrat. Lucru mult mai ok. Firmele de duzina, gen DPD, probabil ca merg la "rupere" si la "clientul pierde nu eu". Nu vreau sa stiu ce minte sclipitoare de la DPD a venit cu ideea sa iti arunce mesajul cu inregistrarea apelului cand te suna curierul. Si daca nu esti ok cu asta si inchizi apelul cum te mai contacteaza sa iti livreze? Cu datele personale la telefon iar nu sunt ok, poti sa fi intr-un loc aglomerat si toata lumea iti aude datele personale. Doar eu am patit sa ii aud unuia tot buletinul? Apoi poate sunt paranoic, insa am un catchall pe un domeniu si la fiecare contract am dat cate o adresa de mail unica. Am patit sa ma sune firme dubioase si asa mi-am dat seama de unde au datele mele. Funny story, am fost sunat de curand sa actualizez datele personale ca sa imi poata furniza serviciile in continuare si pentru ca pandemie e ok si telefonic. Prima intrebare a operatorului foarte bine instruit a fost: Data nasterii ramane aceiasi?
  14. 4 points
    Aici e un forum de baieti discreti pe umarul carora poti plange. @aismen iti poate trimite un cod de introducere.
  15. 3 points
  16. 3 points
    Explozia din Beirut (Liban) NU EXISTA! Ati vazut-o voi? Stiti pe cineva care a murit acolo? Nu e mai grava ca explozia unei petarde! E o minciuna prin care televiziunile vor sa ne sperie si sa ne controleze! Sunt interese mari la mijloc!
  17. 3 points
    Starting at the end of July, Microsoft has begun detecting HOSTS files that block Windows 10 telemetry servers as a 'Severe' security risk. The HOSTS file is a text file located at C:\Windows\system32\driver\etc\HOSTS and can only be edited by a program with Administrator privileges. This file is used to resolve hostnames to IP addresses without using the Domain Name System (DNS). This file is commonly used to block a computer from accessing a remote site by assigning host to the 127.0.0.1 or 0.0.0.0 IP address. For example, if you add the following line to the Windows HOSTS file, it will block users from accessing www.google.com as your browsers will think you are trying to connect to 127.0.0.1, which is the local computer. 127.0.0.1 www.google.com Microsoft now detects HOSTS files that block Windows telemetry Since the end of July, Windows 10 users began reporting that Windows Defender had started detecting modified HOSTS files as a 'SettingsModifier:Win32/HostsFileHijack' threat. When detected, if a user clicks on the 'See details' option, they will simply be shown that they are affected by a 'Settings Modifier' threat and has 'potentially unwanted behavior,' as shown below. SettingsModifier:Win32/HostsFileHijack detection BleepingComputer first learned about this issue from BornCity, and while Microsoft Defender detecting HOSTS hijacks is not new, it was strange to see so many people suddenly reporting the detection [1, 2, 3, 4, 5]. While a widespread infection hitting many consumers simultaneously in the past is not unheard of, it is quite unusual with the security built into Windows 10 today. This led me to believe it was a false positive or some other non-malicious issue. After playing with generic HOSTS file modifications such as blocking BleepingComputer and other sites, I tried adding a blocklist for Microsoft's telemetry to my HOSTS file. This list adds many Microsoft servers used by the Windows operating system and Microsoft software to send telemetry and user data back to Microsoft. As soon as I saved the HOSTS file, I received the following alert stating that I could not save the file as it "contains a virus or potentially unwanted software." I also received alerts that my computer was infected with 'SettingsModifier:Win32/HostsFileHijack.'' HOSTS file blocked from being saved So it seems that Microsoft had recently updated their Microsoft Defender definitions to detect when their servers were added to the HOSTS file. Users who utilize HOSTS files to block Windows 10 telemetry suddenly caused them to see the HOSTS file hijack detection. In our tests, some of the Microsoft hosts detected in the Windows 10 HOSTS file include the following: www.microsoft.com microsoft.com telemetry.microsoft.com wns.notify.windows.com.akadns.net v10-win.vortex.data.microsoft.com.akadns.net us.vortex-win.data.microsoft.com us-v10.events.data.microsoft.com urs.microsoft.com.nsatc.net watson.telemetry.microsoft.com watson.ppe.telemetry.microsoft.com vsgallery.com watson.live.com watson.microsoft.com telemetry.remoteapp.windowsazure.com telemetry.urs.microsoft.com If you decide to clean this threat, Microsoft will restore the HOSTS file back to its default contents. Default Windows 10 HOSTS file Users who intentionally modify their HOSTS file can allow this 'threat,' but it may enable all HOSTS modifications, even malicious ones, going forward. So only allow the threat if you 100% understand the risks involved in doing so. BleepingComputer has reached out to Microsoft with questions regarding this new detection. Via bleepingcomputer.com
  18. 3 points
    Nu e nicio teapa, se numeste HYIP si colcaie internetul de ele. Pe scurt, HYIP = high yield investment program, un fel de ponzi scheme; se face o bursa in care toata lumea baga bani si-i poate cere inapoi oricand, cu un profit care creste liniar in functie de data la care ai investit. Catch-ul e ca in orice moment, site-ul poate decide sa se inchida si sa plece cu banii stransi. Daca ai noroc sa-ti scoti banii inainte sa decida ala sa inchida, ai castigat un profit, de obicei mic, ca tre' sa-i scoti repede, daca nu vrei a ajungi in situatii ca asta. Rareori site-urile/schemele de genul asta asteapta si perioade lungi de timp si lumea chiar apuca sa castige ca lumea (caritas, anybody?), dar in general, astia de le fac prefera sa faca 1000 in paralel si sa stranga sume mici in intervale scurte decat sa se complice cu doua-trei site-uri de lunga durata. Ce ti s-a intamplat se numeste ignoranta. Puteai afla toate astea relativ rapid, chiar si nestiind de concept, cautand despre crypto investments. Get over it. Nu-ti da nimeni crypto inapoi.
  19. 3 points
    Incearca "social engineering". Tu, ea sau cineva apropiat, incercati sa discutati cu individul respectiv si sa vedeti ce vrea si de ce face asta. Poate aflati cate ceva despre el sau poate se da de gol cine e.
  20. 3 points
    De ce sa te complici cu asta? Ce sa mai faca vedetele care au 100k conturi false? Totul depinde de inteligenta oamenilor care o inconjoara pe sora ta, daca ei sunt atat de slab pregatiti incat sa nu recunoasca un cont fals, atunci sorry. Legea atractiei -> daca acorzi atentie chestiilor de genul asta, asta o sa atragi. Pur si simplu trebuie ignorat totul, daca te complici cu declaratii si dosare, la cum se misca lucrurile in ro o sa ai batai si mai mari de cap. Succes!
  21. 3 points
  22. 3 points
    Acel lacat apare doar daca esti un roman adevarat, dac liber si frumos cu frica de 5G. Felicitari!
  23. 3 points
    Urmatoarea intrebare->"Cum formatez partitiile?" Du te si invata cum functionaza un motor de cautare ca sa nu mai primesti mwie pe aici
  24. 3 points
    Eu ma gandeam la ceva de genul: https://tools.ietf.org/html/rfc2324 ( probabil scris de catre @aelius ) De asemenea ar trebui cumva limitata credibilitatea in articolele stiintifice pur teoretice (si greu sau imposibil de demonstrat, ca in teoriile consiratiilor). Desi de la ele ajung mari descoperiri (poate sute de ani mai tarziu) unele sunt pur si simplu idioate. Ori cercetatori care vor sa iasa in evidenta, ori cercetatori care de fapt vor sa descopere droguri noi. Legat de Covid au aparaut desigur sute de mici teorii, inclusiv despre cum se infecteaza o persoana, daca animalele se pot infecta etc. Desi unele erau teoretice, urmau un fir logic si daca le analizai putin ajungeai rapid la concluzia ca "se poate, pare foarte plauzibil". PS: Cercetatorul Nytro de la insitutul de cercetare stiintifica Romanian Security Team a descoperit o modalitate noua de raspandire a Covid-19. Acesta a creat un program informatic (denumit de catre cei din domeniu "Proof of Concept") prin care acesta infecteaza ca un virus routerele (dispozitivele pentru WiFi) si care foloseste undele de 5GHz ale acestora pentru a transmite infectia cu Covid-19 persoanelor din raza de actiune a acestora. Pana in prezent niciun centru ce cercetare nu a demonstrat ca acest lucru nu este posibil. Recomandam tuturor sa opreasca dispozitivele router si sa foloseasca porumbei pentru transferul datelor pe distante scurte.
  25. 3 points
    .md ... asa s-a ajuns sa se faca SEO De un test la inregistrarea pe forum nu se mai aude? Sa scapam de mizerii de genul
  26. 3 points
    Si CIA-ul avea un tool "Sonic Screwdriver" leakuit de wikileaks Vault 7 https://wikileaks.org/vault7/#Dark Matter?cia Edit: nu ar trebui sa te ingrijoreze decat daca incerci pornesti un program nuclear cu care sa poti ameninta alte tari
  27. 3 points
  28. 3 points
    Eu am avut probleme cu enel, care imi "pierduse" niste documente cu caracter personal (copie ci, copie contract casa samd). Desi le dadusem unui agent enel, cand ii tot sunam sa clarific ma puneau sa retrimit. De fiecare data imi comunica robotul ca telefonul este inregistrat. Dupa ce 7 operatori s-au facut ca ploua, am facut plangere la autoritatea care se ocupa cu datele cu caracter personal, le-am dat ora si minutul apelului. In 2 zile m-a sunat enel, cerandu-si scuze ca au ratacit actele si mi-au mai spus ca nu au salvat inregistrarile apelurilor, sac. Din ce stiu, pentru a inregistra apeluri trebuie sa fii operator de date cu caracter personal. 1.trebuie sa fii defapt de acord ca ei sa stocheze inregistrarea telefonica. 2.iti cer ceva care nu e atat de periculos de scurs ca cnpul. Cum ar fi data nasterii sau mail sau adresa. O alta problema mai veche e ca banca (raiff...) vindea datele catre firme de asigurari si m-am trezit sunat de defuncta alico sa imi prezinte o asigurare de viata/sanatate/accident fara sa fiu informat de banca in prealabil ca vor impartasi datele mele personale cu terti. (Aceasta intamplare a fost cu ceva timp inainte de gdpr).
  29. 3 points
    Nu stiu de ce, dar pari genul de om care face asta: - Instalezi windows curat apoi descarci un activator pentru licenta - Intrii pe filelist si descarci un antivirus cu crack, ca astia sunt escroci si cer bani pe ele - Ai impresia ca securitatea se rezuma la un software instalat in cateva click-uri
  30. 3 points
    I indexed all Windows files which appear in Windows update packages, and created a website which allows to quickly view information about the files and download some of them from Microsoft servers. The files that can be downloaded are executable files (currently exe, dll and sys files). Read on for further information. Motivation During a recent research project, I had to track down a bug that Microsoft fixed in one of the drivers. I needed to find out which update fixed the bug. I knew that the bug exists on an unpatched RTM build, and is fixed on a fully patched system. All I needed was the dozens of file versions of that driver, so that I could look at them manually until I find the version that introduced the fix. Unfortunately, to the best of my knowledge there was no place where one could get just these dozens of files without downloading extra GBs of data, be it ISOs or update packages. While searching for the simplest solution, these are the options I considered: Install an unpatched RTM build with automatic updates disabled, and install each update manually. Get the driver file after each installed update. A more efficient option would be to do a binary search, installing the middle update first, and then continuing with the relevant half of the updates depending on whether that update fixed the bug. Extract each version of the file from a Windows package, such as an update package that can be download from the Microsoft Update Catalog or an archive from the Unified Update Platform. Look for the driver files on the internet. There are various fishy “dll fixer” websites that claim to provide versions of system files. Unfortunately, not only that these websites are mostly loaded with ads and the files are sometimes wrapped with a suspicious exe, they also don’t provide any variety of versions for a given file, usually having only one, seemingly randomly selected version. There are also potentially useful services like VirusTotal, but I didn’t find any such service which allows to freely download the files. Option 3 didn’t work, and I chose option 2 over 1 since downloading and extracting update packages seemed quicker than updating the OS every time. I also chose the Microsoft Update Catalog over the Unified Update Platform, since the latter is not really documented and is more obscure, and other than that provides no obvious benefits. Also, the update history is nicely documented by Microsoft: Windows 10 update history. There’s also Windows 7 SP1 update history and Windows 8.1 update history, but I focused on Windows 10. What’s in an update package Each update package that can be downloaded from the Microsoft Update Catalog is an msu file, which is basically a cab archive. Extracting it results in some metadata and another cab archive, which in turn contains the Windows files of the update. The update files are divided to assemblies, each assembly having a manifest file and a folder with the actual files. I expected that it would be enough to grab the file I’m looking for from the corresponding folder, but it turns out that newer update packages contain forward and reverse differentials instead of the actual files. Only 6 KB, no MZ header, clearly not the file I’m looking for. A quick search about the diff patching algorithm didn’t yield results, and I’d need the base Windows version anyway, so this option didn’t look appealing anymore. Just before giving up and trying the other options (the Unified Update Platform and installing updates manually), I looked at the information that is available in the manifest file. The only potentially interesting piece of information that I found is the list of files, which, among various unhelpful (for me) information, contains the file’s SHA256 hash: <?xml version="1.0" encoding="utf-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0" copyright="Copyright (c) Microsoft Corporation. All Rights Reserved."> <assemblyIdentity name="Microsoft-Windows-SMBServer-v2" version="10.0.19041.153" processorArchitecture="amd64" language="neutral" buildType="release" publicKeyToken="31bf3856ad364e35" versionScope="nonSxS" /> <dependency discoverable="no" resourceType="Resources"> <!-- ... --> </dependency> <file name="srv2.sys" destinationPath="$(runtime.drivers)\" sourceName="srv2.sys" importPath="$(build.nttree)\" sourcePath=".\"> <securityDescriptor name="WRP_FILE_DEFAULT_SDDL" /> <asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"> <dsig:Transforms> <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" /> </dsig:Transforms> <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha256" /> <dsig:DigestValue>pD5a0dKSCg7Kc0g1yDyWEX8n8ogPj/niCIy4yUR7WvQ=</dsig:DigestValue> </asmv2:hash> </file> <memberships> <!-- ... --> </memberships> <instrumentation xmlns:ut="http://manifests.microsoft.com/win/2004/08/windows/networkevents" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- ... --> </instrumentation> <localization> <!-- ... --> </localization> <trustInfo> <!-- ... --> </trustInfo> </assembly> You can see it under DigestValue, encoded as base64. In this case, that’s pD5a0dKSCg7Kc0g1yDyWEX8n8ogPj/niCIy4yUR7WvQ= which translates to a43e5ad1d2920a0eca734835c83c96117f27f2880f8ff9e2088cb8c9447b5af4. Can a SHA256 hash help me get the file? Maybe… The Microsoft Symbol Server Having some experience with the Microsoft Symbol Server, I know that it doesn’t only store symbol files, but also the PE (Portable Executable) files themselves. You can refer to the great article Symbols the Microsoft Way by Bruce Dawson for more details, but the most important detail for us is that the format for the path to each PE file in a symbol server is: “%s\%s\%08X%x\%s” % (serverName, peName, timeStamp, imageSize, peName) This means that all we need to retrieve the file from the Microsoft Symbol Server is to know the file’s timestamp and image size. But at this point, we only have the file’s SHA256 hash. VirusTotal to the rescue VirusTotal is a well known service for scanning files and URLs with multiple antivirus products and online scan engines. In addition to the scan results, VirusTotal displays some information about the submitted files. For PE files, it displays information such as imports and resources, but more importantly, it also displays the files’ timestamp and a list of sections. The latter can be used to calculate the file’s image size. In addition, if the file was scanned with VirusTotal before, the information can be retrieved by providing the file hash. That means that for each file previously scanned by VirusTotal, the SHA256 hash is enough to deduce the correct path on the Microsoft Symbol Server and download the file. Back to our example, the a43e5ad1d2920a0eca734835c83c96117f27f2880f8ff9e2088cb8c9447b5af4 hash can be found on VirusTotal, and the parameters that we need are the creation time: Creation Time: 2096-10-28 20:47:11 And the last section in the list of sections: Name: .reloc Virtual Address: 798720 Virtual Size: 12708 … You can Google for an “epoch converter” to convert the creation time to an epoch timestamp: 4002295631, or in hex: 0xee8e2f4f. You might need to append “GMT” to prevent the converter from reading the creation time as a local time. To calculate the image size, just add the virtual address and size of the last section: 798720+12708 = 811428 = 0xc61a4, and then align to the size of a page, which is 0x1000: 0xc7000. Combining the above, we can now build our download link: https://msdl.microsoft.com/download/symbols/srv2.sys/EE8E2F4Fc7000/srv2.sys Here’s a simple Python script which generates a Microsoft Symbol Server link from a file name and a file hash, automating what we just did manually. P.S. In case you’re wondering how come the file was created in 2096, it wasn’t. Starting with Windows 10, the timestamps of the system’s PE files are actually file hashes, a change that was made to allow reproducible builds. For more details see Raymond Chen’s blog post, Why are the module timestamps in Windows 10 so nonsensical?. P.P.S. If you read Bruce Dawson’s article, you saw that he talked about possible collisions in case there are two different files with the same timestamp and image size. He also described how Chrome had this exact problem. But Chrome used real timestamps, what about the pseudo-timestamps which are in fact file hashes that Windows 10 is using? In Windows’ case there are many collisions. I stumbled upon one, and got curious about the actual amount of such collisions, so I wrote a script to find all of them. Here’s the result, 3408 collisions! For most collisions (all but 54) the only different section is .rsrc which contains resource information, which means that the code and the data are the same. Perhaps the hashing algorithm isn’t affected by that section. I took one specific example (aitstatic.exe) and compared my system’s file (in a collision list) with the file served by the symbol server. The two had a different file version, the file served by the symbol server wasn’t signed, and the checksum (the real checksum field in the PE header, not the timestamp-checksum) was different. Also the file that was served by the symbol server was different than all of the files that I found in update packages. Looks like the symbol server sometimes returns a development file instead of a production one, which might be unsigned and have a different version. It might be confusing, and I’ve been bitten by this once, so remember: never trust the version of a file you download from the Microsoft Symbol Server. The other 54 collisions are of .NET PE files, and in this case other sections are different as well. But that doesn’t really matter, since they’re not available via the symbol server at all. Building an index That’s how I solved my problem, downloading several update packages and getting the driver files with the help of VirusTotal. But since all the files are so conveniently available via the Microsoft Symbol Server, I thought that it would be nice to index all of the files once, making the links for all PE files and versions available and saving myself and others from having to go through the procedure in the future. All I had to do is to get the list of updates from the Windows 10 update history page (for now, I looked only at Windows 10 updates), download these updates from the Microsoft Update Catalog, fetch the file names and hashes, query VirusTotal for these hashes, and make some nice interface to search in this index and generate links. Getting the list of updates That was the easy part, a simple Python script did the job. A funny thing I noticed is that the help page titles are edited manually, since they’re almost uniform, but some of them contain minor mistakes. Here are two examples for pages with a properly formatted title: June 18, 2020—KB4567523 (OS Build 19041.331) May 19, 2019—KB4505064 (OS Build 17134.766) And here are a couple of examples of titles with minor mistakes: May 21, 2019—KB4497934 (OS Build OS 17763.529) (an extra “OS”) September 29, 2016 — KB3194496 (OS Builds 14393.222) (“Builds”, but just one build) January 26, 2017—KB 3216755 (OS Build 14393.726) (the only entry with a space after “KB”) July 16, 2019—KB4507465 (OS Build 16299.1296 ) (a space before “)”) Downloading the updates from the Microsoft Update Catalog Most updates are available for three architectures: x86, x64 and ARM64. There are also updates for Windows Server in addition to Windows 10, but most, if not all of them are the same files for both Windows 10 and Windows Server. For now, I decided to limit the scope to x64. This part wasn’t as easy as the previous one, mainly because it’s so time consuming. In addition, it turned out that not all of the updates are available in the Microsoft Update Catalog. Out of the 502 updates available for Windows 10 while writing these lines, only 355 are available for x64. Out of the 147 which aren’t available, 27 are for Windows 10 Mobile (discontinued), one is only for x86, and one is only for Windows Server 2016. The other 118 are truly missing, 2 of which have a “no longer available” notice, and the others’ absence is not explained. Here is a detailed table with all of the updates and their availability for x64. Querying VirusTotal There are files of various types in the update packages, including non-PE files such as txt and png. For now, I decided to focus on exe, dll and sys which are the most common PE file types, even though there are other PE file types such as scr. Querying VirusTotal is quite simple, as I demonstrated with the Python script in the previous section about VirusTotal. The problem was that I needed to query information about 134,515 files, which is not a small amount. I was afraid of a strict rate limiting, but fortunately, the rate limiting wasn’t so strict. After a while I got a response similar to the following: { "error": { "code": "TooManyRequestsError", "message": "More than 1000 requests from 66.249.66.153 within a hour" } } So no more than 1000 requests within an hour, which means 5.5 days of downloading. I could use more computers, but that would be inconvenient. Even though it’s not too bad, I was uncomfortable seeing my script waiting every hour for the next quota of 1000 requests, so I used PyMultitor, the Python Multi Threaded Tor Proxy tool created by Tomer Zait. I heard about the tool a while ago, and finally had the perfect use case for it. I was pleasantly surprised how stable and easy to use it is (stability should also be attributed to the Tor project). With PyMultitor, I was able to reduce the time to 3 days of downloading. Of course, no data is returned if a file was never submitted to VirusTotal. Out of the 134,515 files, 108,470 were submitted, which is a success rate of 80.6%. Not bad! Also, 190 of the files were submitted, but the report for them didn’t contain details about the PE format. Rescanning them solved the problem. The result After building the index of files, I created a simple website which displays the data in a table. Here it is: Winbindex - the Windows Binaries Index All the files that were found in the update packages are listed, but currently only exe, dll and sys files have download links, except for those that weren’t submitted to VirusTotal. Possible further work I think that the index can already be very useful, but it’s not complete. Here are some things that can be done to further improve it: Indexing files from base builds. Currently, files which don’t appear in any update package, but appear in the initial Windows release aren’t indexed. To fill the gap, I’ll probably have to get the corresponding ISO files of the initial Windows releases. Indexing files which aren’t available on VirusTotal. There are several possible options here: Automating a VM that updates itself and grabs all the files. Understanding the diff algorithm to be able to get all the files from the update packages. Using the Unified Update Platform, although I’m not familiar enough with it to say if it can help with this. Indexing files of other architectures: x86 and ARM64, and of other Windows versions: Windows 7, Windows 8/8.1. I don’t plan to do any of that in the near future, but I might do that one day when I stumble upon another task which requires it. Source m417z.com
  31. 3 points
  32. 2 points
    A fost generata defapt de 2 antene de 5G care s-au intersectat.
  33. 2 points
    One Byte to rule them all Posted by Brandon Azad, Project Zero For the last several years, nearly all iOS kernel exploits have followed the same high-level flow: memory corruption and fake Mach ports are used to gain access to the kernel task port, which provides an ideal kernel read/write primitive to userspace. Recent iOS kernel exploit mitigations like PAC and zone_require seem geared towards breaking the canonical techniques seen over and over again to achieve this exploit flow. But the fact that so many iOS kernel exploits look identical from a high level begs questions: Is targeting the kernel task port really the best exploit flow? Or has the convergence on this strategy obscured other, perhaps more interesting, techniques? And are existing iOS kernel mitigations equally effective against other, previously unseen exploit flows? In this blog post, I'll describe a new iOS kernel exploitation technique that turns a one-byte controlled heap overflow directly into a read/write primitive for arbitrary physical addresses, all while completely sidestepping current mitigations such as KASLR, PAC, and zone_require. By reading a special hardware register, it's possible to locate the kernel in physical memory and build a kernel read/write primitive without a fake kernel task port. I'll conclude by discussing how effective various iOS mitigations were or could be at blocking this technique and by musing on the state-of-the-art of iOS kernel exploitation. You can find the proof-of-concept code here. I - The Fellowship of the Wiring A struct of power While looking through the XNU sources, I often keep an eye out for interesting objects to manipulate or corrupt for future exploits. Soon after discovering CVE-2020-3837 (the oob_timestamp vulnerability), I stumbled across the definition of vm_map_copy_t: struct vm_map_copy { int type; #define VM_MAP_COPY_ENTRY_LIST 1 #define VM_MAP_COPY_OBJECT 2 #define VM_MAP_COPY_KERNEL_BUFFER 3 vm_object_offset_t offset; vm_map_size_t size; union { struct vm_map_header hdr; /* ENTRY_LIST */ vm_object_t object; /* OBJECT */ uint8_t kdata[0]; /* KERNEL_BUFFER */ } c_u; }; This looked interesting to me for several reasons: The structure has a type field at the very start, so an out-of-bounds write could change it from one type to another, leading to type confusion. Because iOS is little-endian, the least significant byte comes first in memory, meaning that even a single-byte overflow would be sufficient to set the type to any of the three values. The type discriminates a union between arbitrary controlled data (kdata) and kernel pointers (hdr and object). Thus, corrupting the type could let us directly fake pointers to kernel objects without needing to perform any reallocations. I remembered reading about vm_map_copy_t being used as an interesting primitive in past exploits (before iOS 10), though I couldn't remember where or how it was used. vm_map_copy objects were also used by Ian Beer in Splitting atoms in XNU. So, vm_map_copy looks like a possibly interesting target for corruption; however, it's only truly interesting if the code uses it in a truly interesting way. Digging through osfmk/vm/vm_map.c, I found that vm_map_copyout_internal() does indeed use the copy object in a very interesting way. But first, let's talk a little more about what vm_map_copy is and how it works. A vm_map_copy represents a copy-on-write slice of a process's virtual address space which has been packaged up, ready to be inserted into another virtual address space. There are three possible internal representations: as a list of vm_map_entry objects, as a vm_object, or as an inline array of bytes to be directly copied into the destination. We'll focus on types 1 and 3. Fundamentally, the ENTRY_LIST type is the most powerful and general representation, while the KERNEL_BUFFER type is strictly an optimization. A vm_map_entry list consists of several allocations and several layers of indirection: each vm_map_entry describes a virtual address range [vme_start, vme_end) that is being mapped by a specific vm_object, which in turn contains a list of vm_pages describing the physical pages backing the vm_object. Meanwhile, if the data being inserted is not shared memory and if the size is roughly two pages or less, then the vm_map_copy is simply over-allocated to hold the data contents inline in the same allocation, no indirection or further allocations required. As a consequence of this optimization, the 8 bytes of the vm_map_copy object at offset 0x20 can be either a pointer to the head of a vm_map_entry list, or fully attacker-controlled data, all depending on the type field at the start. So corrupting the first byte of a vm_map_copy object causes the kernel to interpret arbitrary controlled data as a vm_map_entry pointer. With this understanding of vm_map_copy internals, let's turn back to vm_map_copyout_internal(). This function is responsible for taking a vm_map_copy and inserting it into the destination address space (represented by type vm_map_t). It is reachable when sharing memory between processes by sending an out-of-line memory descriptor in a Mach message: the out-of-line memory is stored in the kernel as a vm_map_copy, and vm_map_copyout_internal() is the function that inserts it into the receiver's process. As it turns out, things get rather exciting if vm_map_copyout_internal() processes a corrupted vm_map_copy containing a pointer to a fake vm_map_entry hierarchy. In particular, consider what happens if the fake vm_map_entry claims to be wired, which causes the function to try to fault in the page immediately: kern_return_t vm_map_copyout_internal( vm_map_t dst_map, vm_map_address_t *dst_addr, /* OUT */ vm_map_copy_t copy, vm_map_size_t copy_size, boolean_t consume_on_success, vm_prot_t cur_protection, vm_prot_t max_protection, vm_inherit_t inheritance) { ... if (copy->type == VM_MAP_COPY_OBJECT) { ... } ... if (copy->type == VM_MAP_COPY_KERNEL_BUFFER) { ... } ... vm_map_lock(dst_map); ... adjustment = start - vm_copy_start; ... /* * Adjust the addresses in the copy chain, and * reset the region attributes. */ for (entry = vm_map_copy_first_entry(copy); entry != vm_map_copy_to_entry(copy); entry = entry->vme_next) { ... entry->vme_start += adjustment; entry->vme_end += adjustment; ... /* * If the entry is now wired, * map the pages into the destination map. */ if (entry->wired_count != 0) { ... object = VME_OBJECT(entry); offset = VME_OFFSET(entry); ... while (va < entry->vme_end) { ... m = vm_page_lookup(object, offset); ... vm_fault_enter(m, // Calls pmap_enter_options() dst_map->pmap, // to map m->vmp_phys_page. va, prot, prot, VM_PAGE_WIRED(m), FALSE, /* change_wiring */ VM_KERN_MEMORY_NONE, /* tag - not wiring */ &fault_info, NULL, /* need_retry */ &type_of_fault); ... offset += PAGE_SIZE_64; va += PAGE_SIZE; } } } ... vm_map_copy_insert(dst_map, last, copy); ... vm_map_unlock(dst_map); ... } Let's walk through this step-by-step. First, other vm_map_copy types are handled: if (copy->type == VM_MAP_COPY_OBJECT) { ... } ... if (copy->type == VM_MAP_COPY_KERNEL_BUFFER) { ... } The vm_map is locked: vm_map_lock(dst_map); We enter a for loop over the linked list of (fake) vm_map_entry objects: for (entry = vm_map_copy_first_entry(copy); entry != vm_map_copy_to_entry(copy); entry = entry->vme_next) { We handle the case where the vm_map_entry is wired and should thus be faulted in immediately: if (entry->wired_count != 0) { When set, we loop over every virtual address in the wired entry. Since we control the contents of the fake vm_map_entry, we can control the object pointer (of type vm_object) and offset value that are read: object = VME_OBJECT(entry); offset = VME_OFFSET(entry); ... while (va < entry->vme_end) { We look up the vm_page struct for each physical page of memory that needs to be wired in. Since we control the fake vm_object and the offset, we can cause vm_page_lookup() to return a pointer to a fake vm_page struct whose contents we control: m = vm_page_lookup(object, offset); And finally, we call vm_fault_enter() to fault in the page: vm_fault_enter(m, // Calls pmap_enter_options() dst_map->pmap, // to map m->vmp_phys_page. va, prot, prot, VM_PAGE_WIRED(m), FALSE, /* change_wiring */ VM_KERN_MEMORY_NONE, /* tag - not wiring */ &fault_info, NULL, /* need_retry */ &type_of_fault); The call to vm_fault_enter() is rather complicated, so I won't put the code here. Suffice to say, by setting fields in our fake objects appropriately, it is possible to navigate vm_fault_enter() with a fake vm_page object in order to reach a call to pmap_enter_options() with a completely arbitrary physical page number: kern_return_t pmap_enter_options( pmap_t pmap, vm_map_address_t v, ppnum_t pn, vm_prot_t prot, vm_prot_t fault_type, unsigned int flags, boolean_t wired, unsigned int options, __unused void *arg) pmap_enter_options() is responsible for modifying the page tables of the destination to insert the translation table entry that will establish a mapping from a virtual address to a physical address. Analogously to how vm_map manages the state for the virtual mappings of an address space, the pmap struct manages the state for the physical mappings (i.e. page tables) of an address space. And according to the sources in osfmk/arm/pmap.c, no further validation is performed on the supplied physical page number before the translation table entry is added. Thus, our corrupted vm_map_copy object actually gives us an incredibly powerful primitive: mapping arbitrary physical memory directly into our process in userspace! An old friend I decided to build the POC for the vm_map_copy physical memory mapping technique on top of the kernel read/write primitive provided by the oob_timestamp exploit for iOS 13.3. There were two primary reasons for this. First, I did not have a good bug available to develop a complete exploit with it. Even though I had initially stumbled upon the idea while trying to exploit the oob_timestamp bug, it quickly became apparent that that bug wasn't a good fit for this technique. Second, I wanted to evaluate the technique independently of the vulnerability or vulnerabilities used to achieve it. It seemed that there was a good chance that the technique could be made deterministic (that is, without a failure case); implementing it on top of an unreliable vulnerability would make it hard to evaluate separately. This technique most naturally fits a controlled one-byte linear heap overflow in any of the allocator zones kalloc.80 through kalloc.32768 (i.e., general-purpose allocations of between 65 and 32768 bytes). For ease of reference in the rest of this post, I'll simply call it the one-byte exploit technique. Leaving the Shire We've already laid out the bones of the technique above: create a vm_map_copy of type KERNEL_BUFFER containing a pointer to a fake vm_map_entry list, corrupt the type to ENTRY_LIST, receive it with vm_map_copyout_internal(), and get arbitrary physical memory mapped into our address space. However, successful exploitation is a little bit more complicated: We still have not addressed where this fake vm_map_entry/vm_object/vm_page hierarchy will be constructed. We need to ensure that the kernel thread that calls vm_map_copyout_internal() does not crash, panic, or deadlock after mapping the physical page. Mapping one physical page is great, but probably not sufficient by itself to achieve arbitrary kernel read/write. This is because: The kernelcache's exact load address in physical memory is unknown, so we cannot map any specific page of it directly without locating it first. It is possible that some hardware device exposes an MMIO interface that is powerful enough by itself to build some sort of read/write primitive; however, I'm not aware of any such component. Thus, we will need to map more than one physical address, and most likely we will need to use data read from one mapping to find the physical address to use for another. This means our mapping primitive can not be one-shot. 4. The call to vm_map_copy_insert() after the for loop tries to zfree() the vm_map_copy to the vm_map_copy_zone. This will panic given a vm_map_copy originally of type KERNEL_BUFFER, since KERNEL_BUFFER objects are initially allocated using kalloc(). Thus, the only way to safely break out of the for loop and resume normal operation is to first get kernel read/write and then patch up state in the kernel to prevent this panic. These constraints will guide the course of this exploit technique. A short cut to PAN An important prerequisite for the one-byte technique is to create a fake vm_map_entry object hierarchy at a known address. Since we are already building this POC on oob_timestamp, I decided to leverage a neat trick I picked up while exploiting that bug. In the real world, another vulnerability in addition to the one-byte overflow might be needed to leak a kernel address. While developing the POC for oob_timestamp, I learned that the AGXAccelerator kernel extension provides a very interesting primitive: IOAccelSharedUserClient2 and IOAccelCommandQueue2 together allow the creation of large regions of pageable memory shared between userspace and the kernel. Having access to user/kernel shared memory can be extremely helpful when developing exploits, since you can place fake kernel data structures there and manipulate them while the kernel accesses them. Of course, this AGXAccelerator primitive is not the only way to get kernel/user shared memory; the physmap, for example, also maps most of DRAM into virtual memory, so it can also be used to reflect userspace memory contents into the kernel. However, the AGXAccelerator primitive is often much more convenient in practice: for one, it provides a very large contiguous shared memory region in a much more constrained address range; and for two, it's easier to leak addresses of adjacent objects to locate it. Now, before the iPhone 7, iOS devices did not support the Privileged Access Never (PAN) security feature. This meant that all of userspace was effectively shared memory with the kernel, and you could just overwrite pointers in the kernel to point to fake data structures in userspace. However, modern iOS devices enable PAN, so attempts by the kernel to directly access userspace memory will fault. This is what makes the existence of the AGXAccelerator shared memory primitive so useful: if you can establish a large shared memory region and learn its address in the kernel, that's basically equivalent to having PAN turned off. Of course, a key part of that sentence is "and learn its address in the kernel"; doing that usually requires a vulnerability and some effort. Instead, as we already rely on oob_timestamp, we will simply hardcode the shared memory address and note that finding the address dynamically is left as an exercise for the reader. At the sign of the panicking POC With kernel read/write and a user/kernel shared memory buffer in hand, we are ready to write the POC. The overall flow of the exploit is essentially what was outlined above. We start by creating the shared memory region in the kernel. We initialize a fake vm_map_entry list inside the shared memory. The entry list contains 3 entries: a "ready" entry, a "mapping" entry, and a "done" entry. Together these entries will represent the current state of each mapping operation. We send an out-of-line memory descriptor containing a fake vm_map_header in a Mach message to a holding port. The out-of-line memory is stored in the kernel as a vm_map_copy object of type KERNEL_BUFFER (value 3). We simulate a one-byte linear heap overflow that corrupts the type field of the vm_map_copy, changing it to ENTRY_LIST (value 1). We start a thread that receives the Mach message queued on the holding port. This triggers a call to vm_map_copyout_internal() on the corrupted vm_map_copy. Due to the way the vm_map_entry list was initially configured, the vm_map_copyout thread will spin in an infinite loop on the "done" entry, ready for us to manipulate it. At this point, we have a kernel thread that is spinning ready to map any physical page we request. To map a page, we first set the "ready" entry to link to itself, and then set the "done" entry to link to the "ready" entry. This will cause the vm_map_copyout thread to spin on "ready". While spinning on "ready", we mark the "mapping" entry as wired with a single physical page and link it to the "done" entry, which we link to itself. We also populate the fake vm_object and vm_page to map the desired physical page number. Then, we can perform the mapping by linking the "ready" entry to the "mapping" entry. vm_map_copyout_internal() will map in the page and then spin on the "done" entry, signaling completion. This gives us a reusable primitive that maps arbitrary physical addresses into our process. As an initial proof of concept, I mapped the non-existent physical address 0x414140000 and tried to read from it, triggering an LLC bus error from EL0: The mines of memory At this point we have proved that the mapping primitive is sound, but we still don't know what to do with it. My first thought was that the easiest approach would be to go after the kernelcache image in memory. Note that on modern iPhones, even with a direct physical read/write primitive, KTRR prevents us from modifying the locked down portions of the kernel image, so we can't just patch the kernel's executable code. However, certain segments of the kernelcache image remain writable at runtime, including the part of the __DATA segment that contains sysctls. Since sysctls have been (ab)used before to build read/write primitives, this felt like a stable path forward. The challenge was then to use the mapping primitive to locate the kernelcache in physical memory, so that the sysctl structs could then be mapped into userspace and modified. But first, before we figure out how to locate the kernelcache, some background on physical memory on the iPhone 11 Pro. The iPhone 11 Pro has 4 GB of DRAM based at physical address 0x800000000, so physical DRAM addresses span 0x800000000 to 0x900000000. Of this, the range 0x801b80000 to 0x8ec9b4000 is reserved for the Application Processor (AP), the main processor of the phone which runs the XNU kernel and applications. Memory outside this region is reserved for coprocessors like the Always On Processor (AOP), Apple Neural Engine (ANE), SIO (possibly Apple SmartIO), AVE, ISP, IOP, etc. The addresses of these and other regions can be found by parsing the devicetree or by dumping the iboot-handoff region at the start of DRAM. At boot time, the kernelcache is loaded contiguously into physical memory, which means that finding a single kernelcache page is sufficient to locate the whole image. Also, while KASLR may slide the kernelcache by a large amount in virtual memory, the load address in physical memory is quite constrained: in my testing, the kernel header was always loaded at an address between 0x805000000 and 0x807000000, a range of just 32 MB. As it turns out, this range is smaller than the kernelcache itself at 0x23d4000 bytes, or 35.8 MB. Thus, we can be certain at runtime that address 0x807000000 contains a kernelcache page. However, I quickly ran into panics when trying to map the kernelcache: panic(cpu 4 caller 0xfffffff0156f0c98): "pmap_enter_options_internal: page belongs to PPL, " "pmap=0xfffffff031a581d0, v=0x3bb844000, pn=2103160, prot=0x3, fault_type=0x3, flags=0x0, wired=1, options=0x1" This panic string purports to come from the function pmap_enter_options_internal(), which is in the open-source part of XNU (osfmk/arm/pmap.c), and yet the panic is not present in the sources. Thus, I reversed the version of pmap_enter_options_internal() in the kernelcache to figure out what was happening. The issue, I learned, is that the specific page I was trying to map was part of Apple's Page Protection Layer (PPL), a portion of the XNU kernel that manages page tables and that is considered even more privileged than the rest of the kernel. The goal of PPL is to prevent an attacker from modifying protected pages (in particular, executable code pages for codesigned binaries) even after compromising the kernel to obtain a read/write capability. In order to enforce that protected pages cannot be modified, PPL must protect page tables and page table metadata. Thus, when I tried to map a PPL-protected page into userspace, it triggered a panic. if (pa_test_bits(pa, 0x4000 /* PP_ATTR_PPL? */)) { panic("%s: page belongs to PPL, " ...); } if (pvh_get_flags(pai_to_pvh(pai)) & PVH_FLAG_LOCKDOWN) { panic("%s: page locked down, " ...); } The presence of PPL significantly complicates use of the physical mapping primitive, since trying to map a PPL-protected page will panic. And the kernelcache itself contains many PPL-protected pages, splitting the contiguous 35 MB binary into smaller PPL-free chunks that no longer bridge the physical slide of the kernelcache. Thus, there is no longer a single physical address we can (safely) map that is guaranteed to be a kernelcache page. And the rest of the AP's DRAM region is an equally treacherous minefield. Physical pages are grabbed for use by PPL and returned to the kernel as-needed, and so at runtime PPL pages are scattered throughout physical memory like mines. Thus, there is no static address anywhere that is guaranteed not to blow up. A map showing the protection flags on every page of AP DRAM on the A13 over time. Yellow is PPL+LOCKDOWN, red is PPL, green is LOCKDOWN, and blue is unguarded (i.e., mappable). II - The Two Techniques The road to DRAM's guard Yet, that's not quite true. The Application Processor's DRAM region might be a minefield, but anything outside of it is not. That includes the DRAM used by coprocessors and also any other addressable components of the system, such as hardware registers for system components that are typically accessed via memory-mapped I/O (MMIO). With such a powerful primitive, I expect that there are a plethora of techniques that could be used to build a read/write primitive. And I expect that there are many clever things that could be done by leveraging direct access to special hardware registers and coprocessors. Unfortunately, this is not an area with which I'm very familiar, so I'll just describe one (failed) attempt to bypass PPL here. The idea I had was to take control of some coprocessor and use execution on both the coprocessor and the AP together to attack the kernel. First, we use the physical mapping primitive to modify the part of DRAM storing data for a coprocessor in order to get code execution on that coprocessor. Next, back on the main processor, we use the mapping primitive a second time to map and disable the coprocessor's Device Address Resolution Table, or DART (basically an IOMMU). With code execution on the coprocessor and the corresponding DART disabled, we have direct unguarded access from the coprocessor to physical memory, allowing us to completely sidestep the protections of PPL (which are only enforced from the AP). However, whenever I tried to modify certain regions of DRAM used by coprocessors, I would get kernel panics. In particular, the region 0x800000000 - 0x801564000 appeared to be readonly: panic(cpu 5 caller 0xfffffff0189fc598): "LLC Bus error from cpu1: FAR=0x16f507f10 LLC_ERR_STS/ADR/INF=0x11000ffc00000080/0x214000800000000/0x1 addr=0x800000000 cmd=0x14(acc_cifl2c_cmd_ncwr)" panic(cpu 5 caller 0xfffffff020ca4598): "LLC Bus error from cpu1: FAR=0x15f03c000 LLC_ERR_STS/ADR/INF=0x11000ffc00000080/0x214030800104000/0x1 addr=0x800104000 cmd=0x14(acc_cifl2c_cmd_ncwr)" panic(cpu 5 caller 0xfffffff02997c598): "LLC Bus error from cpu1: FAR=0x10a024000 LLC_ERR_STS/ADR/INF=0x11000ffc00000082/0x21400080154c000/0x1 addr=0x80154c000 cmd=0x14(acc_cifl2c_cmd_ncwr)" This was very weird: these addresses are outside of the KTRR lockdown region, so nothing should be able to block writing to this part of DRAM with a physical mapping primitive! Thus, there must be some other undocumented lockdown enforced on this physical range. On the other hand, the region 0x801564000 - 0x801b80000 remains writable as expected, and writing to different areas in this region produces odd system behaviors, supporting the theory that this is corrupting data used by coprocessors. For example, writing to some areas would cause the camera and flashlight to become unresponsive, while writing to other areas would cause the phone to panic when the mute slider was switched on. To get a better sense of what might be happening, I identified the regions in this range by examining the devicetree and dumping memory. In the end, I discovered the following layout of coprocessor firmware segments in the range 0x800000000 - 0x801b80000: Thus, the regions that are locked down are all __TEXT segments of coprocessor firmwares; this strongly suggests that Apple has added a new mitigation to make coprocessor __TEXT segments read-only in physical memory, similar to KTRR on the AMCC (probably Apple's memory controller) but for coprocessor firmwares instead of just the AP kernel. This might be the undocumented CTRR mitigation referenced in the originally published xnu-6153.41.3 sources that appears to be an enhanced replacement for KTRR on A12 and up; Ian Beer suggested CTRR might stand for Coprocessor Text Readonly Region. Nevertheless, code execution on these coprocessors should still be viable: just as KTRR does not prevent exploitation on the AP, the coprocessor __TEXT lockdown mitigation does not prevent exploitation on coprocessors. So, even though this mitigation makes things more difficult, at this point our plan of disabling a DART and using code execution on the coprocessor to write to a PPL-protected physical address should still work. The voice of PPL What did turn out to be a roadblock however was the DART/IOMMU lockdown enforced by PPL on the Application Processor. At boot, XNU parses the "pmap-io-ranges" property in the devicetree to populate the io_attr_table array, which stores page attributes for certain physical I/O addresses. Then, when trying to map the physical address, pmap_enter_options_internal() checks the attributes to see if certain mappings should be disallowed: wimg_bits = pmap_cache_attributes(pn); // checks io_attr_table if ( flags ) wimg_bits = wimg_bits & 0xFFFFFF00 | (u8)flags; pte |= wimg_to_pte(wimg_bits); if ( wimg_bits & 0x4000 ) { xprr_perm = (pte >> 4) & 0xC | (pte >> 53) & 1 | (pte >> 53) & 2; if ( xprr_perm == 0xB ) pte_perm_bits = 0x20000000000080LL; else if ( xprr_perm == 3 ) pte_perm_bits = 0x20000000000000LL; else panic("Unsupported xPRR perm ..."); pte = pte_perm_bits | pte & ~0x600000000000C0uLL; } pmap_enter_pte(pmap, pte_p, pte, vaddr); Thus, we can only map the DART's I/O address into our process if bit 0x4000 is clear in the wimg field. Unfortunately, a quick look at the "pmap-io-ranges" property in the devicetree confirmed that bit 0x4000 was set for every DART: addr len wimg signature 0x620000000, 0x40000000, 0x27, 'PCIe' 0x2412C0000, 0x4000, 0x4007, 'DART' ; dart-sep 0x235004000, 0x4000, 0x4007, 'DART' ; dart-sio 0x24AC00000, 0x4000, 0x4007, 'DART' ; dart-aop 0x23B300000, 0x4000, 0x4007, 'DART' ; dart-pmp 0x239024000, 0x4000, 0x4007, 'DART' ; dart-usb 0x239028000, 0x4000, 0x4007, 'DART' ; dart-usb 0x267030000, 0x4000, 0x4007, 'DART' ; dart-ave ... 0x8FC3B4000, 0x4000, 0x40004016, 'GUAT' ; sgx.gfx-handoff-base Thus, we cannot map the DART into userspace to disable it. The palantír Even though PPL prevents us from mapping page tables and DART I/O addresses, the physical I/O addresses for other hardware components are still mappable. Thus, it is still possible to map and read some system component's hardware registers to try and locate the kernel. My initial attempt was to read from IORVBAR, the Reset Vector Base Address Register accessible via MMIO. The reset vector is the first piece of code that executes on a CPU after it resets; thus, reading IORVBAR would give us the physical address of XNU's reset vector, which would pinpoint the kernelcache in physical memory. IORVBAR is mapped at offset 0x40000 after the "reg-private" address for each CPU in the devicetree; for example, on A13 CPU 0 it is located at physical address 0x210050000. It is part of the same group of register sets containing CoreSight and DBGWRAP that had been previously used to bypass KTRR. However, I found that IORVBAR is not accessible on A13: trying to read from it will panic. I spent some time searching the A13 SecureROM for interesting physical addresses before Jann Horn suggested that I map the KTRR lockdown registers on the AMCC, Apple's memory controller. These registers store the physical memory bounds of the KTRR region in order to enforce the KTRR readonly region against attacks from coprocessors. Mapping and reading the AMCC's RORGNBASEADDR register at physical address 0x200000680 worked like a charm, yielding the start address of the lockdown region containing the kernelcache in physical memory. Using security mitigations to break other security mitigations is fun. The back gate is closed After finding a definitive way forward using AMCC, I looked at one last possibility before giving up on bypassing PPL. iOS is configured with 40-bit physical addresses and 16K pages (14 bits). Meanwhile, the arbitrary physical page number passed to pmap_enter_options_internal() is 32 bits, and is shifted by 14 and masked with 0xFFFF_FFFF_C000 when inserted into the level 3 translation table entry (L3 TTE). This means that we could control bits 45 - 14 of the TTE, even though bits 45 - 40 should always be zero based on the physical address size programmed in TCR_EL1.IPS. If the hardware ignored the bits beyond the maximum supported physical address size, then we could bypass PPL by supplying a physical page number that exactly matches the DART I/O address or page table page, but with one of the high bits set. Having the high bits set would cause the mapped address to fail to match any of the addresses in "pmap-io-ranges", even though the TTE would map the same physical address. This would be neat as it would allow us to bypass PPL as a precursor to kernel read/write/execute, rather than the other way around. Unfortunately, it turns out that the hardware does in fact check that TTE bits beyond the supported physical address size are zero. Thus, I went forward with the AMCC trick to locate the kernelcache instead. The taming of sysctl At this point, we have a physical read/write primitive for non-PPL physical addresses, and we know the address of the kernelcache in physical memory. The next step is to build a virtual read/write primitive. I decided to stick with known techniques for this part: using the fact that the sysctl_oid tree used by the sysctl() syscall is stored in writable memory in the kernelcache to manipulate it and convert benign sysctls allowed by the app sandbox into kernel read/write primitives. XNU inherited sysctls from FreeBSD; they provide access to certain kernel variables to userspace. For example, the "hw.l1dcachesize" readonly sysctl allows a process to determine the L1 data cache line size, while the "kern.securelevel" read/write sysctl controls the "system security level" used for some operations in the BSD portion of the kernel. The sysctls are organized into a tree hierarchy, with each node in the tree represented by a sysctl_oid struct. Building a kernel read primitive is as simple as mapping the sysctl_oid struct for some sysctl that is readable in the app sandbox and changing the target variable pointer (oid_arg1) to point to the virtual address we want to read. Invoking the sysctl then reads that address. Using sysctls to build a write primitive is a bit more complicated, since no sysctls are listed as writable in the container sandbox profile. The ziVA exploit for iOS 10.3.1 worked around this by changing the oid_handler field of the sysctl to call copyin(). However, on PAC-enabled devices like the A13, oid_handler is protected with a PAC, meaning that we cannot change its value. However, when disassembling the function hook_system_check_sysctlbyname() that implements the sandbox check for the sysctl() system call, I noticed an interesting undocumented behavior: // Sandbox check sysctl-read ret = sb_evaluate(sandbox, 116u, &context); if ( !ret ) { // Sandbox check sysctl-write if ( newlen | newptr && (namelen != 2 || name[0] != 0 || name[1] != 3) ) ret = sb_evaluate(sandbox, 117u, &context); else ret = 0; } For some reason, if the sysctl node is deemed readable inside the sandbox, then the write check is not performed on the specific sysctl node { 0, 3 }! What this means is that { 0, 3 } will be writable in every sandbox from which it is readable, regardless of whether or not the sandbox profile allows writes to that sysctl. As it turns out, the name of the sysctl { 0, 3 } is "sysctl.name2mib", which is a writable sysctl used to convert the string-name of a sysctl into the numeric form, which is faster to look up. It is used to implement sysctlnametomib(). So it makes sense that this sysctl should usually be writable. The upshot is that even though there are no writable sysctls specified in the sandbox profile, sysctl { 0, 3 } is in fact writable anyways, allowing us to build a virtual write primitive alongside our read primitive. Thus, we now have full arbitrary kernel read/write. III - The Return of the Copyout The battle of pmap fields We have come far, but the journey is not yet done: we must break the ring. As things stand, vm_map_copyout_internal() is spinning in an infinite loop on the "done" vm_map_entry, whose vme_next pointer points to itself. We must guide the safe return of this function to preserve the stability of the system. There are two basic issues preventing this. First, because we've inserted entries into our page tables at the pmap layer without creating corresponding virtual entries at the vm_map layer, there is currently an accounting conflict between the pmap and vm_map views of our address space. This will cause a panic on process exit if not addressed. Second, once the loop is broken, vm_map_copyout_internal() has a call to vm_map_copy_insert() that will panic trying to free the corrupted vm_map_copy to the wrong zone. We will address the pmap/vm_map conflict first. Suppose for the moment that we were able to break out of the for loop and allow vm_map_copyout_internal() to return. The call to vm_map_copy_insert() that occurs after the for loop walks through all the entries in the vm_map_copy, unlinks them from the vm_map_copy's entry list, and links them into the vm_map's entry list instead. static void vm_map_copy_insert( vm_map_t map, vm_map_entry_t after_where, vm_map_copy_t copy) { vm_map_entry_t entry; while (vm_map_copy_first_entry(copy) != vm_map_copy_to_entry(copy)) { entry = vm_map_copy_first_entry(copy); vm_map_copy_entry_unlink(copy, entry); vm_map_store_entry_link(map, after_where, entry, VM_MAP_KERNEL_FLAGS_NONE); after_where = entry; } zfree(vm_map_copy_zone, copy); } Since the vm_map_copy's vm_map_entrys are all fake objects residing in shared memory, we really do not want them linked into our vm_map's entry list, where they will be freed on process exit. The simplest solution is thus to update the corrupted vm_map_copy's entry list so that it appears to be empty. Forcing the vm_map_copy's entry list to appear empty certainly lets us safely return from vm_map_copyout_internal(), but we would nevertheless still get a panic once our process exits: panic(cpu 3 caller 0xfffffff01f4b1c50): "pmap_tte_deallocate(): pmap=0xfffffff06cd8fd10 ttep=0xfffffff0a90d0408 ptd=0xfffffff132fc3ca0 refcnt=0x2 \n" The issue is that during the course of the exploit, our mapping primitive forces pmap_enter_options() to insert level 3 translation table entries (L3 TTEs) into our process's page tables, but the corresponding accounting at the vm_map layer never happens. This disagreement between the pmap and vm_map views matters because the pmap layer requires that all physical mappings be explicitly removed before the pmap can be destroyed, and the vm_map layer will not know to remove a physical mapping if there is no vm_map_entry describing the corresponding virtual mapping. Due to PPL, we can not update the pmap directly, so the simplest solution is to grab a pointer to a legitimate vm_map_entry with faulted-in pages and overlay it on top of the virtual address range at which pmap_enter_options() established our physical mappings. Thus we will update the corrupted vm_map_copy's entry list so that it points to this single "overlay" entry instead. The fires of stack doom Finally, it is time to break vm_map_copyout_internal() out of the for loop. for (entry = vm_map_copy_first_entry(copy); entry != vm_map_copy_to_entry(copy); entry = entry->vme_next) { The macro vm_map_copy_to_entry(copy) expands to: (struct vm_map_entry *)(&copy->c_u.hdr.links) Thus, in order to break out of the loop, we need to process a vm_map_entry with vme_next pointing to the address of the c_u.hdr.links field in the corrupted vm_map_copy originally passed to this function. The function is currently spinning on the "done" vm_map_entry, and we need to link in one final "overlay" vm_map_entry to address the pmap/vm_map accounting issue anyway. So the simplest way to break the loop is to modify the "overlay" entry's vme_next to point to &copy->c_u.hdr.links. and then update the "done" entry's vme_next to point to the overlay entry. The problem is the call to vm_map_copy_insert() mentioned earlier, which frees the vm_map_copy as if it were of type ENTRY_LIST: zfree(vm_map_copy_zone, copy); However, the object passed to zfree() is our corrupted vm_map_copy, which was allocated with kalloc(); trying to free it to the vm_map_copy_zone will panic. Thus, we somehow need to ensure that a different, legitimate vm_map_copy object gets passed to the zfree() instead. Fortunately, if you check the disassembly of vm_map_copyout_internal(), the vm_map_copy pointer is spilled to the stack for the duration of the for loop! FFFFFFF007C599A4 STR X28, [SP,#0xF0+copy] FFFFFFF007C599A8 LDR X25, [X28,#vm_map_copy.links.next] FFFFFFF007C599AC CMP X25, X27 FFFFFFF007C599B0 B.EQ loc_FFFFFFF007C59B98 ... ; The for loop FFFFFFF007C59B98 LDP X9, X19, [SP,#0xF0+dst_addr] FFFFFFF007C59B9C LDR X8, [X19,#vm_map_copy.offset] This makes it easy to ensure that the pointer passed to zfree() is a legitimate vm_map_copy allocated from the vm_map_copy_zone: just scan the kernel stack of the vm_map_copyout_internal() thread while it's still spinning and swap any pointers to the corrupted vm_map_copy with the legitimate one. At last, we have fixed up the state enough to allow vm_map_copyout_internal() to break the loop and return safely. Homeward bound Finally, with a virtual kernel read/write primitive and the vm_map_copyout_internal() thread safely returned, we have achieved our goal: a stable kernel compromise achieved by turning a one-byte controlled heap overflow directly into an arbitrary physical address mapping primitive. Or rather, a nearly-arbitrary physical address mapping primitive. As we have seen, PPL-protected addresses like page table pages and DARTs cannot be mapped using this technique. When I started on this journey, I had intended to demonstrate that the conventional approach of going after the kernel task port was both unnecessary and limiting, that other kernel read/write techniques could be equally powerful. I suspected that the introduction of Mach-port based techniques in iOS 10 had biased the sample of publicly-disclosed exploits in favor of Mach-port oriented vulnerabilities, and that this in turn obscured other techniques that were just as promising but publicly less well understood. The one-byte technique initially seemed to offer a counterpoint to the mainstream exploit flow. After reading the code in vm_map.c and pmap.c, I had expected to be able to simply map all of DRAM into my address space and then implement kernel read/write by performing manual page table walks using those mappings. But it turned out that PPL blocks this technique on modern iOS by preventing certain pages from being mapped at all. It's interesting to note that similar research was touched upon years ago as well, back when such a thing would have worked. While doing background research for this blog post, I came across a presentation by Azimuth called iOS 6 Kernel Security: A Hacker’s Guide that introduced no fewer than four separate primitives that could be constructed by corrupting various fields of vm_map_copy_t: an adjacent memory disclosure, an arbitrary memory disclosure, an extended heap overflow, and a combined address disclosure and heap overflow at the disclosed address. At the time of the presentation, the KERNEL_BUFFER type had a slightly different structure, so that c_u.hdr.links.next overlapped a field storing the vm_map_copy's kalloc() allocation size. It might have still been possible to turn a one-byte overflow into a physical memory mapping primitive on some platforms, but it would have been harder since it would require mapping the NULL page and a shared address space. However, a larger overflow like those used in the four aforementioned techniques could certainly change both the type and the c_u.hdr.links.next fields. After its apparent public introduction in that Azimuth presentation by Mark Dowd and Tarjei Mandt, vm_map_copy corruption was repeatedly cited as a widely used exploit technique. See for example: From USR to SVC: Dissecting the 'evasi0n' Kernel Exploit by Tarjei Mandt; Tales from iOS 6 Exploitation by Stefan Esser; Attacking the XNU Kernel in El Capitan by Luca Todesco; Shooting the OS X El Capitan Kernel Like a Sniper by Liang Chen and Qidan He; iOS 10 - Kernel Heap Revisited by Stefan Esser; iOS kernel exploitation archaeology by Patroklos Argyroudis; and *OS Internals, Volume III: Security and Insecurity by Jonathan Levin, in particular Chapter 18 on TaiG. Given the prevalence of these other forms of vm_map_copy corruption, it would not surprise me to learn that someone had discovered the physical mapping primitive as well. Then, in OS X 10.11 and iOS 9, the vm_map_copy struct was modified to remove the redundant allocation size and inline data pointer fields in KERNEL_BUFFER instances. It is possible that this was done to mitigate the frequent abuse of this structure in exploits, although it's hard to tell because those fields were redundant and could have been removed simply to clean up the code. Regardless, removing those fields changed vm_map_copy into its current form, weakening the precondition required to carry out this technique to a single byte overflow. The mitigating of the Shire So, how effective were the various iOS kernel exploit mitigations at blocking the one-byte technique, and how effective could they be if further hardened? The mitigations I considered were KASLR, PAN, PAC, PPL, and zone_require. Many other mitigations exist, but either they don't apply to the heap overflow bug class or they aren't sensible candidates to mitigate this particular technique. First, kernel address space layout randomization, or KASLR. KASLR can be divided into two parts: the sliding of the kernelcache image in virtual memory and the randomization of the kernel_map and submaps (zone_map, kalloc_map, etc.), collectively referred to as the "kernel heap". The kernel heap randomization means that you do need some way to determine the address of the kernel/user shared memory buffer in which we build the fake VM objects. However, once you have the address of the shared buffer, neither form of randomization has much bearing on this technique, for two reasons: First, generic iOS kernel heap shaping primitives exist that can be used to reliably place almost any allocation in the target kalloc zones before a vm_map_copy allocation, so randomization does not block the initial memory corruption. Second, after the corruption occurs, the primitive granted is arbitrary physical read/write, which is independent of virtual address randomization. The only address randomization which does impact the core exploit technique is that of the kernelcache load address in physical memory. When iOS boots, iBoot loads the kernelcache into physical DRAM at a random address. As discussed in Part I, this physical randomization is quite small at 32 MB. However, improved randomization would not help because the AMCC hardware registers can be mapped to locate the kernelcache in physical memory regardless of where it is located. Next consider PAN, or Privileged Access Never. This is an ARMv8.1 security mitigation that prevents the kernel from directly accessing userspace virtual memory, thereby preventing the common technique of overwriting pointers to kernel objects so that they point to fake objects living in userspace. Bypassing PAN is a prerequisite for this technique: we need to establish a complex hierarchy of vm_map_entry, vm_object, and vm_page objects at a known address. While hardcoding the shared buffer address is good enough for this POC, better techniques would be needed for a real exploit. PAC, or Pointer Authentication Codes, is an ARMv8.3 security feature introduced in Apple's A12 SOC. The iOS kernel uses PAC for two purposes: first as an exploit mitigation against certain common bug classes and techniques, and second as a form of kernel control flow integrity to prevent an attacker with kernel read/write from gaining arbitrary code execution. In this setting, we're only interested in PAC as an exploit mitigation. Apple's website has a table showing how various types of pointers are protected by PAC. Most of these pointers are automatically PAC-protected by the compiler, and the biggest impact of PAC so far is on C++ objects, especially in IOKit. Meanwhile, the one-byte exploit technique only involves vm_map_copy, vm_map_entry, vm_object, and vm_page objects, all plain C structs in the Mach part of the kernel, and so is unaffected by PAC. However, at BlackHat 2019, Ivan Krstić of Apple announced that PAC would soon be used to protect certain "members of high value data structures", including "processes, tasks, codesigning, the virtual memory subsystem, [and] IPC structures". As of May 2020, this enhanced PAC protection has not yet been released, but if implemented it might prove effective at blocking the one-byte technique. The next mitigation is PPL, which stands for Page Protection Layer. PPL creates a security boundary between the code that manages page tables and the rest of the XNU kernel. This is the only mitigation besides PAN that impacted the development of this exploit technique. In practice, PPL could be much stricter about which physical addresses it allows to be mapped into a userspace process. For example, there is no legitimate use case for a userspace process to have access to kernelcache pages, so setting a flag like PVH_FLAG_LOCKDOWN on kernelcache pages could be a weak but sensible step. More generally, addresses outside the Application Processor's DRAM region (including physical I/O addresses for hardware components) could probably be made unmappable for most processes, perhaps with an entitlement escape hatch for exceptional cases. Finally, the last mitigation is zone_require, a software mitigation introduced in iOS 13 that checks that some kernel pointers are allocated from the expected zalloc zone before using them. I don't believe that XNU's zone allocator was initially intended as a security mitigation, but the fact remains that many objects that are frequently targeted during exploits (in particular ipc_ports, tasks, and threads) are allocated from a dedicated zone. This makes zone checks an effective funnel point for detecting exploitation shenanigans. In theory, zone_require could be used to protect almost any object allocated from a dedicated zone; in practice, though, the vast majority of zone_require() checks in the kernelcache are on ipc_port objects. Because the one-byte technique avoids the use of fake Mach ports altogether, none of the existing zone_require() checks apply. However, if the use of zone_require were expanded, it is possible to partially mitigate the technique. In particular, inserting a zone_require() call in vm_map_copyout_internal() once the vm_map_copy has been determined to be of type ENTRY_LIST would ensure that the vm_map_copy cannot be a KERNEL_BUFFER object with a corrupted type. Of course, like all mitigations, this isn't 100% robust: using the technique in an exploit would probably still be possible, but it might require a better initial primitive than a one-byte overflow. "Appendix A": Annals of the exploits In my opinion, the one-byte exploit technique outlined in this blog post is a divergence from the conventional strategies employed at least since iOS 10. Fully 19 of the 24 original public exploits that I could find since iOS 10 used dangling or fake Mach ports as an intermediate exploitation primitive. And of the 20 exploits released since iOS 10.3 (when Apple initially started locking down the kernel task port), 18 of those ended by constructing a fake kernel task port. This makes Mach ports the defining feature of modern public iOS kernel exploitation. Having gone through the motions of using the one-byte technique to build a kernel read/write primitive on top of a simulated heap overflow, I certainly can see the logic of going after the kernel task port instead. Most of the exploits I looked at since iOS 10 have a relatively modular design and a linear flow: an initial primitive is obtained, state is manipulated, an exploitation technique is applied to build a stronger primitive, state is manipulated again, another technique is applied after that, and so on, until finally you have enough to build a fake kernel task port. There are checkpoints along the way: initial corruption, dangling Mach port, 4-byte read primitive, etc. The exact sequence of steps in each case is different, but in broad strokes the designs of different exploits converge. And because of this convergence, the last steps of one exploit are pretty much interchangeable with those of any other. The design of it all "feels clean". That modularity is not true of this one-byte technique. Once you start the vm_map_copyout_internal() loop, you are committed to this course until after you've obtained a kernel read/write primitive. And because vm_map_copyout_internal() holds the vm_map lock for the duration of the loop, you can't perform any of the virtual memory operations (like allocating virtual memory) that would normally be integral steps in a conventional exploit flow. Writing this exploit thus feels different, more messy. All that said, and at the risk of sounding like I'm tooting my own horn, the one-byte technique intuitively feels to me somewhat more "technically elegant": it turns a weaker precondition directly into a very strong primitive while sidestepping most mitigations and avoiding most sources of instability and slowness seen in public iOS exploits. Of the 24 iOS exploits I looked at, 22 depend on reallocating a slot for an object that has been recently freed with another object, many doing so multiple times; with the notable exception of SockPuppet, this is an inherently risky operation because another thread could race to reallocate that slot instead. Furthermore, 11 of the 19 exploits since iOS 11 depend on forcing a zone garbage collection, an even riskier step that often takes a few seconds to complete. Meanwhile, the one-byte technique has no inherent sources of instability or substantial time costs. It looks more like the type of technique I would expect sophisticated attackers would be interested in developing. And even if something goes wrong during the exploit and a bad address is dereferenced in the kernel, the fact that the vm_map lock is held means that the fault results in a deadlock rather than a kernel panic, making the failed exploit look like a frozen process instead of a system crash. (You can even "kill" the deadlocked app in the app switcher UI and then continue using the device afterwards.) "Appendix B": Conclusions I'll conclude by returning to the three questions posed at the very beginning of this post: These questions are all too "fuzzy" to have real answers, but I'll attempt to answer them anyway. To the first question, I think the answer is no, the kernel task port is not the singular best exploit flow. In my opinion the one-byte technique is just as good by most measures, and in my personal opinion, I expect there are other as-yet unpublished techniques that are also equally good. To the second question, on whether the convergence on the kernel task port has obscured other techniques: I don't think there is enough public iOS research to say conclusively, but my intuition is yes. In my own experience, knowing the type of bug I'm looking for has influenced the types of bugs I find, and looking at past exploits has guided my choice in exploit flow. I would not be surprised to learn others feel similarly. Finally, are existing iOS kernel exploit mitigations effective against unseen exploit flows? Immediately after I developed the POC for the one-byte technique, I had thought the answer was no; but here at the end of this journey, I'm less certain. I don't think PPL was specifically designed to prevent this technique, but it offers a very reasonable place to mitigate it. PAC didn't do anything to block the technique, but it's plausible that a future expansion of PAC-protected pointers would. And despite the fact that zone_require didn't impact the exploit at all, a single-line addition would strengthen the required precondition from a single-byte overflow to a larger overflow that crosses a zone boundary. So, even though in their current form Apple's kernel exploit mitigations were not effective against this unseen technique, they do lay the necessary groundwork to make mitigating the technique straightforward. Indices One final parting thought. In Deja-XNU, published 2018, Ian Beer mused about what the "state-of-the-art" of iOS kernel exploitation might have looked like four years prior: This is an important question to consider because, as defenders, we almost never get to see the capabilities of the most sophisticated attackers. If a gap develops between the techniques used by attackers in private and the techniques known to defenders, then defenders may waste resources mitigating against the wrong techniques. I don't think this technique represents the current state-of-the-art; I'd guess that, like Deja-XNU, it might represent the state-of-the-art of a few years ago. It's worth considering what direction the state-of-the-art may have taken in the meantime. Source
  34. 2 points
    Microsoft says file downloads signed with the SHA-1 algorithm are insecure and will be removed on August 3, 2020. Microsoft announced this week plans to remove all Windows-related file downloads from the Microsoft Download Center that are cryptographically signed with the Secure Hash Algorithm 1 (SHA-1). The files will be removed next Monday, on August 3, the company said on Tuesday. The OS maker cited the security of the SHA-1 algorithm for the move. SHA-1, BROKEN SINCE 2016 Most software companies have recently begun abandoning the SHA-1 algorithm after a team of academics broke the SHA-1 hashing function at a theoretical level in February 2016. The algorithm was broken in a real-world practical attack in February 2017, when Google cryptographers disclosed SHAttered, a technique that could make two different files appear as they had the same SHA-1 file signature. At the time, creating an SHA-1 collision was considered computationally expensive, and Google experts thought SHA-1 could still be used in practice for at least half a decade until the cost would go down. However, subsequent research released in May 2019 and in January 2020, detailed an updated methodology to cut down the cost of an SHA-1 collision attack to under $110,000 and then to under $50,000. Since 2016, software makers have abandoned SHA-1, mainly for SHA-2. Google removed SHA-1 support from Chrome with the release of Chrome 56, at the end of January 2017; Firefox removed SHA-1 support in Firefox 51, also released at the end of January 2017; and Microsoft dropped support for SHA-1 in Edge and Internet Explorer in mid-2017. Apple followed by removing SHA-1 from iOS 13 and macOS Catalina, and OpenSSH announced plans to deprecate SHA-1 for its login process earlier this year. Microsoft, since August 2019, no longer uses SHA-1 to sign and authenticate Windows OS updates. Currently, Microsoft is in the process of replacing SHA-1 with SHA-2 across its products. However, the OS maker didn't specify if the Windows-related files that are being removed from its downloads center on Monday will be replaced with new download links signed with SHA-2, leaving many too wonder if they'll ever be able to download some of Microsoft's old tools. Via zdnet.com
  35. 2 points
    ce plm e asta? ma simt ca in 2002.
  36. 2 points
  37. 2 points
    Adica angajatii puteau sa faca ce voiau in mediu de PRD? Ahahahahahahahahaha. Zici ca e reclama la FNI.
  38. 2 points
    Si-a pus leo ca e zodia leu 😄😄😄😄 Si cyber ca e in saibar speis. Cred.
  39. 2 points
    Multumesc oricum sper ca nu te-am plictisit cu intrebarea asta banala pentru un forum de informarica, nu prea sunt bun in demoniul asta eu sunt de alta profesie. 😘
  40. 2 points
  41. 2 points
    Mister equality of outcome right here. Sunt curios daca esti capabil sa definesti un sistem de valori pe baza a ceea ce crezi tu ca va salva lumea. Pentru ca vad ca te consideri intelectual, altfel nu ai avea pareri atat de radicale impotriva intregului sistem actual.
  42. 2 points
    STAGIU DE VOLUNTARIAT / PRACTICĂ LA CERT-RO Directorul General al CERT-RO Dan Cîmpean caută un număr de patru (4) voluntari pe perioada: 21 Iulie 2020 - 15 Septembrie 2020 , care sunt interesați să trăiască timp de două (2) luni experiența profesională a unui Director din Centrul Național de Răspuns la Incidente de Securitate Cibernetică. Condiții de participare: · Student(ă) sau absolvent(ă) de studii superioare · Cunoștințe de limba engleză nivel cel puțin mediu · Interesat(ă) de a activa, lucra și învăța în una din instituțiile de vârf ale Guvernului României · Un (1) student și o (1) studentă din București, ce vor activa la CERT-RO · Un (1) student și o (1) studentă din județe, ce vor activa online · Disponibilitate de a activa in medie 2 ore pe zi, flexibil. Selecția se va face de către Departamentul HR al CERT-RO pe baza CV-urilor primite. CV-ul trebuie trimis la adresa de mail HR@CERT.RO până la data de 17 iulie 2020, 23:59.
×
×
  • Create New...