# Media

url: https://www.youtube.com/watch?v=mYLa1f6LoLI
title: DEF CON 31 - Still Vulnerable Out of the Box - Ryan Johnson, Mohamed Elsabagh, Angelos Stavrou
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=mYLa1f6LoLI",
    "title": "DEF CON 31 - Still Vulnerable Out of the Box - Ryan Johnson, Mohamed Elsabagh, Angelos Stavrou",
    "description": "Prepaid Android smartphones present an attractive option since they can be used and discarded at will without significant financial cost. The reasons for their use are manifold, although some people may use them to dissemble their true identity. Prepaid smartphones offer value, but there may be an additional \"cost\" for their cheap price. We present an examination of the local attack surface of 21 prepaid Android smartphones sold by American carriers (and 11 unlocked smartphones). While examining these devices, we discovered instances of arbitrary command execution in the context of a \"system\" user app, arbitrary AT command execution, arbitrary file write in the context of the Android System (i.e., \"system_server\"), arbitrary file read/write in the context of a \"system\" user app, programmatic factory reset, leakage of GPS coordinates to a loopback port, numerous exposures of non-resettable device identifiers to system properties, and more.\n\nThe only user interaction that our threat model assumes is that the user installs and runs a third-party app that has no permissions or only a single \"normal\" level permission that is automatically granted to the third-party app upon installation. The installed third-party app can leverage flaws in pre-loaded software to escalate privileges to indirectly perform actions or obtain data while lacking the necessary privileges to do so directly. Due to a wide range of local interfaces with missing access control checks and inadequate input validation, a third-party app\u2019s behavior is not truly circumscribed by the permissions that it requests. Due to the common inclusion of pre-loaded software from Android vendors, chipset manufacturers, carriers, and vendor partners, exploit code can have significant breadth. The inter-app communication used to exploit these vulnerabilities may be difficult to classify as inherently malicious in general since it uses the standard communication channels employed by non-malicious apps.\n\nWe pick up again where we left off from our DEF CON 26 talk \u2026 raiding the prepaid Android smartphone aisles at Walmart. We provide another snapshot on the state of security for Android carrier devices. In this talk, we examine 21 different prepaid Android smartphones being sold by the major American carriers, and we also cover 11 unlocked Android devices, which are primarily ZTE smartphones. We identified vulnerabilities in multiple layers of the Android software stack. For each discovered vulnerability, we step through the attack requirements, access vector, and attack workflow in order to help developers and bug hunters identify common software flaws going forward.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2585,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   All right, thanks everyone.  My name is Ryan Johnson, and today I'm  going to be giving a talk called Still Vulnerable Out  of the Box, Revisiting the Security of Prepaid Android  Carrier Devices.  And I collaborated with Angelo Stavro and Mohamed El-Sabag  for this research.  So today, just the agenda, we're going to start off  talking about Android, then look at some  of the preloaded software.  Then we'll move on to applications  and their application components.  After that, we'll move to application IPC.  Then we'll get to the core of the talk,  which is vulnerabilities in prepaid Android carrier  devices.  After that, we'll move to some CTE-specific vulnerabilities.  And then we'll zoom out a little bit,  look at some of the vulnerability root causes,  move on to how to secure the software,  and wrap it up with some conclusions.  And this talk is somewhat like a continuation of the talk  we gave at DEF CON 26 in 2018, essentially  on the same topic, looking at vulnerabilities  in Android prepaid carrier devices, so five years later,  just showing that the issue still persists.  So we all work for Quokka, which is previously  known as CryptoWire.  We were jump-started in 2011 on a DARPA project.  We've also worked with DHS S&T, NIST.  And at Quokka, we do software assurance,  developer integration, personal device management,  firmware testing, threat feed, and security analytics.  So prepaid smartphones, these are  going to be smartphones that you generally  purchase in full price at the time of purchase.  And you generally get a prepaid service contract.  This is going to be a fixed term service contract, usually  one maybe to three months.  Some of these smartphones are typically on the low end,  so they could be anywhere from $50 up to maybe $300 or $400.  The major American carriers have a presence  in the prepaid smartphone market.  You can see there's a picture there  from Walmart showing T-Mobile, AT&T, as well as Verizon.  So in the prepaid market, Verizon  has a large presence, since they own Total by Verizon, which  used to be called Total Wireless.  They also own TrackPhone, as well as Straight Talk.  So Android is developed and maintained by Google.  So they make the source code available  through the Android Open Source Project, also known as AOSP.  So Android is an open ecosystem where  vendors can take a version of Android,  fork it, and then modify it to provide extra hardware  and software features, which gives them  kind of a differentiation in the market  and a competitive advantage.  And this is good, since it gives you  something beyond plain vanilla Android.  But it also requires some scrutiny  from a security perspective.  Some of the major Android vendors  have their own security bulletin.  So if there's a vulnerability in their own code, which  is not present in AOSP, then they  will list it on their security bulletin.  And Android, it's the most popular mobile OS in the world.  It's 70.8%, and in America, with 42%.  So when you have an Android device,  various entities are going to provide some software.  So there's AOSP, which is at the core of it from Google.  There's going to be the chipset manufacturer and the hardware  manufacturer.  They're going to add some hardware components, as well  as some software components.  If it's a carrier device, they usually  put on some software as well.  There's the vendor, which does the customization.  And then there's also vendor partners,  which is anyone from Netflix to Facebook to some app  you've never heard of that doesn't have a launcher or an  app icon.  So pre-installed software, this is  necessary to make your device more  functional than just a brick.  So some of the software is necessary.  Some of it is value added, where the vendor thinks  that you will find this useful.  So pre-installed software is more trusted  and has more privileges than third-party applications,  because it's specifically curated  by the device or the vendor or OEM.  So pre-installed applications get special access  to permissions.  They can run as certain special UIDs and run system services.  And on Android, processes are bound by an SE Linux domain,  as well as the rules that apply to that domain.  And a lot of this pre-installed software  may contain insecure interfaces,  which third-party apps that you download can interact with.  And in Android, the main IPC mechanism is called an intent.  And you can think of this as a message with a destination,  as well as some embedded data.  So Android applications, when you install them,  they have their own user ID, as well as  group ID, which are assigned at installation time.  And this helps to provide a sandbox for the application's  files and resources.  In Android, applications are identified  using a package name.  This is generally reverse domain notation.  And in Android, applications get access  to data and capabilities using permissions.  So an application will declare what permissions it needs.  And there's different levels of permissions.  Normal permissions are granted to an application  upon installation.  And then dangerous permissions are,  at least for third-party applications, to get them,  they have to prompt the user with either an accept  or reject dialogue.  And a user can also download an app  and assign it to a specific role.  So maybe you download an app.  You want it to be the default VPN,  or you want it to be the default messenger,  or a notification listener.  This is, again, done through the GUI.  And Android apps are not monolithic.  You can decompose them into individual units  called application components.  And in Android, they provide an activity,  which is essentially a user interface that the user can  interact with, service for long-running tasks,  broadcast receiver registers for events,  somewhat like an event listener.  And a content provider provides access to structured data.  So application components, they can be started independently.  They can run concurrently.  And they perform dedicated tasks.  And all apps in Android have a manifest file.  And this is somewhat like a specification,  which has their package name, version information,  permissions they request, listing of application  components, and any hardware or software requirements.  And for an external app to interact  with an application component in another file,  this is dictated by three attributes, which  are listed in the manifest for the declaration of an app  component.  Android exported needs to be true.  Android enables can't be false.  And an application component can set a permission,  which is like an access permission.  So for an external app to interact with it,  to send it a message, it needs to possess that permission.  So here are some ways that some IPC mechanisms,  either done directly or indirectly, many of these  are provided by Binder in Android.  Some of the ones we'll talk about today  are intents, bound services, and network sockets.  So the threat model is a local application  that has either 0 or 1 normal level permission.  And a normal level permission is granted to the application  upon installation.  And the application, based on that 0 or 1 permission,  appears limited and constrained.  We're not requiring any user interaction  beyond installing and running a third party application once.  And then once this application is run,  it turns to its environment and interacts  with insecure interfaces of co-located software  on the device, generally through intents, bound services,  and sockets.  So onto the carrier devices.  We looked at 21 Android carrier devices.  They are grouped by carrier, showing the vendor as well  as the model.  So you can see TrackPhone is pretty well represented  because they're a pretty big player in the prepaid market.  And here is a summary of the vulnerabilities  in these devices.  So 86% of them leak non-resettable device  identifiers to system properties.  81% of them leak the GPS coordinates  to a loopback port, like a debug port on TCP port 7000.  9% of the devices expose arbitrary file read  and write as a system UID.  There's also 24% of them are impacted by a factory reset.  And this is when, essentially, you  wipe the user's apps, the app data, as well as the settings.  So if you have any data that isn't backed up or synced  externally, your data is gone forever.  So the user can experience data loss.  There's also arbitrary AT command execution,  which an AT command is a command that's  sent to the baseband processor, which  is executed by the modem.  24% of the devices were impacted.  And most severe is arbitrary command execution  as a system UID.  And 9% of the devices were impacted.  So I mentioned earlier that this talk  is a continuation of the talk we did at DEF CON 26.  So here is a listing of the devices, as well as  the carrier, and the model, and then the vulnerabilities  that were present in each.  So non-resettable device identifiers,  these are data items like the IMEI, the Wi-Fi MAC address,  Bluetooth MAC address, serial number, the ICC ID.  And back in Android 9, there was the read phone state  permission, which an application could request.  And if the user granted it to the application,  then the application could get these non-resettable device  identifiers.  And then in Android 10, Google made some changes.  So the permission was read privilege phone state instead  of read phone state, which made it  so that third party applications could no longer access  these device identifiers.  Although pre-installed apps can get the read privilege phone  state permission, access the device identifiers,  and then leak them to a location which  is accessible to a zero permission  third party application.  And a common leakage location we noticed was system properties.  So system properties, this is a system-wide repository  of key value pairs.  You can see the get prop being executed  with a snippet of the output.  And the get prop command can be executed by any application.  It doesn't require any permissions.  SE Linux can actually restrict access to certain system  property keys.  That's not the ones we're going to talk about.  They're accessible by a third party app  with zero permissions.  So the system properties contain version information  of the build, version information  about the chipset, status of init services, and much more.  And third party applications cannot write  to system properties, which is enforced by SE Linux.  So here are the system property key names,  as well as the non-resettable device ID that it leaks,  as well as the devices that are impacted.  So as you can see here, the IMA is fairly common,  as well as the Bluetooth, or the Wi-Fi MAC address,  and the serial number.  So based on the previous table, there's  just a small code snippet executing the get prop command  and then grepping on all of those patterns.  And then it reads from the command output  and just writes it to the system log.  And as you can see here, this is being run on the track phone  TCL A3X, which here, a zero permission app  can get the device IMA, the ICC ID,  as well as the Bluetooth MAC address.  Next, there is on certain Android devices,  they contain a system binary from MediaTek called MNLD.  And the vulnerability here is whenever  the GPS module is active, MNLD will open a debug port  on the loopback interface, TCP port 7000,  that doesn't perform any authentication  or authorization to any clients that connect.  It just starts emitting the GPS coordinates.  And the attack requirements here is just a local application  that has been granted the internet permission.  You can see the impacted devices, as well as the path.  This system binary executes with the GPS user ID,  and you can see the CVE there.  And this appeared in MediaTek's May 2023 security bulletin,  and they've provided the affected chipsets.  We've noticed there's different behavior among versions,  major Android versions for MNLD.  So on Android 11, 12, and 13, MNLD  will bind to the loopback interface on port 7000, which  in hex is 1B58.  And then on Android 9 and below, it will bind to any IP address.  And we observed this going down to Android 4.4.2 device, which  is Android KitKat, which is quite old.  And at the bottom is just a source code snippet  to connect to port 7000 on the loopback interface,  read from the socket, and then write the output  to the system log.  So here is some output from connecting to the debug port.  It emits NMEA sentences.  And we've redacted the latitude and longitude  from the GPS coordinates here, and we've  listed the NMEA sentences that contain the device's GPS  coordinates.  So there's two different attack models you could do.  You could have a passive approach  where an application that has the internet permission just  periodically pulls port 7000 in the background  to see when it's open.  And whenever it's open, it can then just  get the device's GPS coordinates,  record this longitudinally.  There's also an active approach where a malicious application  can start Google Maps or a similar type of application.  And if you've used Google Maps and given it  access to your location, then as soon  as you start the application's launcher activity,  it will immediately activate the GPS module, which  will then open TCP port 7000, which an application can then  connect to in the background and get the device's GPS  coordinates.  We also searched the GNGGA NMEA sentence on Shodan,  and there's 930 internet-facing devices that  are emitting that NMEA string.  And 913 of them are from port 7000.  Next, we're going to talk about the MMI Group app.  This is a pre-installed app that exposes various capabilities,  which I will talk about on the next slide.  The attack requirements are just a local app  with no permissions necessary.  You can see the impacted devices listed.  The package name is com.factory.mmigroup.  On all the devices we looked at, it always  had a version name of 2.1 and a version code of 3.  It executes as a system UID, and the reserved CVE ID  is shown on the slide.  So these are the capabilities that it exposes,  broken down by device.  So there's a factory reset, which I mentioned earlier  is a data wipe.  It also leaks the device IMEI, the device serial number,  and exposes arbitrary AT command execution.  And you can enable wireless adapters.  So the workflow for this is the local malicious app  sends an intent to the MMI Group receiver in the MMI Group app.  The MMI Group app starts.  It then dynamically registers for various action strings.  The malicious app then sends a broadcast intent  using those action strings that it registered for  and puts the embedded data that the MMI Group is expecting.  The MMI Group then either queries some data  or performs an action, and it writes the result  to persist.sys ATA ADB result system property.  And the malicious app then reads either the data  or the result of executing the action  from that same system property.  And at the bottom is just a small source code snippet  to send a broadcast intent, which initiates a factory reset.  So the more interesting vulnerability here  is arbitrary AT command injection.  So this application executes a set AT command for AT plus  power where the actual parameter is controlled by an intent  extra that an external app can send.  And the AT power AT command is not actually  supported on the devices we examined,  and it's also not in the 3GPP standard.  So to inject our own command, we look at AT plus power equals.  That string is nine characters, so we  inject the backspace escape sequence nine times  or its Unicode equivalent, and then put our own AT command  and send that broadcast intent, and then  check the result from the persist sys ATA ADB result  system property.  So there's a source code snippet there  where we inject nine backspace characters  and then execute the AT plus CNUM, which returns  the device's phone number, which is then  read from system properties.  So here's a demo on a T-Mobile Rebel 6 Pro 5G.  Here's the ATT&CK app showing that it has no permissions,  and it's going to execute AT commands in the background.  So just getting the device's phone number,  getting the IMEI, getting the base station  ID, which is a proxy for its location,  getting the ICC ID, getting the EMSI, getting the serial number,  calling 911, showing that 911 has been called,  and then programmatically hanging up.  Next, we have another application  that also exposes arbitrary AT command  execution to co-located apps.  The ATT&CK requirements is just a local app.  It doesn't require any permissions.  The package name is com.trackphone.tfstatus.  As you can see by the path, the file name is hiddenmenu.apk.  This executes with the radio UID,  which is the UID that the telephony framework runs  on Android.  So this is a very similar type of vulnerability  where it's executing a different set AT command where  we can control the parameter, which  is from an intent extra.  So this, the only difference is it's 11 characters long.  And so we just inject 11 backspace characters.  And there's also another approach  where you can stack additional AT commands by turning  that AT command into a test AT command  by injecting a question mark and then adding additional AT  commands, which are separated by a carriage return.  So at the bottom, you can see there  that it's just injecting 11 backspace characters,  resetting the settings for the modem,  and then calling 911 again.  So we have another hidden menu app.  And as you can see, these applications  are not that hidden.  The vulnerability here is that it  exposes a programmatic factory reset to co-located apps.  Again, it's a data wipe where a user could potentially  encounter catastrophic data loss.  The attack requirements is a local application  that hasn't been granted any permissions.  The impacted device is a Boost Mobile TCL20XE.  The package name, you can see, is  com.tctGCSHiddenMenuProxy, the version name, version code,  and that it runs as a system UID.  And at the bottom is essentially just a broadcast intent  where you send a message or an intent  to factory reset receiver.  And once it starts, it just programmatically  initiates a factory reset.  In Android, application components  can set an access permission that external applications must  possess to interact with them.  So here, there's a vulnerability where  it says I'm protected by this permission.  But if that permission isn't declared either by that app,  by any other pre-installed apps, or the Android framework,  then a third party app can then declare that permission,  set the access requirements for it,  and then interact with any application components which  are supposed to be protected by it.  So we observed this in the TCL screen recorder app.  And the vulnerability here is that it  exposes arbitrary file read and write as a system user  app to local applications.  The attack requirements are just an application  that declares the missing permission  and then requests it.  The impacted device is a track phone and AT&T TCL30Z.  The package name is com.tclscreenrecorder.  And we've provided the version names, version codes,  and it runs as a system UID.  So the workflow is this malicious app  declares and requests the missing permission, which  is com.tct.smart.switchphone.permission.switchdata  in its manifest, and then also requests it.  It then binds to the service that  requires this access permission that it just declared.  After it binds to the service, it gets an iBinder, which it  then embeds into a messenger.  It then gets a message from this messenger,  creates its own messenger, and then sets it  to the reply to instance field in the message  with a what value of 1, and then sends it  to the TCT screen recorder app.  And this is for bidirectional communication.  And then on that messenger, it invokes function number 4,  which is essentially just a what value of 4.  It provides the file it wants to access,  which in this case, example, just SD card,  defcon31.txt on external storage,  as well as the mode, which would either be read or write.  Then the TCT screen recorder app  responds to the messenger that was provided in step 3  that the malicious app receives.  In the bundle, there's an extra name file descriptor,  which contains a parcel file descriptor, which it can then  put into a file input stream for reading,  or a file output stream for writing,  and perform whatever operation it wanted to on the file  that it indicated.  So there's something called factory apps.  These kind of provide a centralized location  for testing of hardware and software functionality.  These can come by many different names, engineering apps,  or hidden menu apps, factory apps.  These generally cannot be disabled or uninstalled  by the user.  You would need root access or potentially an exploit  to remove or disable them.  They run with a system UID, which  makes them quite privileged.  Generally, there's no launcher activity,  so the user is unlikely to actually use them.  So we talked about the MMI group already.  Now we'll cover the FQC app, as well as the Transion Factory  app.  So the Evenwell FQC app, this exposes  local arbitrary command execution  to co-located applications.  The attack requirements is just a local app  with no permissions necessary.  And the impacted devices are the Verizon Sharp Rovo 5  and the Tracfone BlueView 2.  The package name is com.evenwell.fqc.  You can see the vulnerable version names, version codes,  the path it runs as a system UID, and the reserved CVE ID.  So this one kind of has an interesting workflow.  The malicious app starts the show barometer activity.  The FQC app then starts this activity.  And when this activity comes into the foreground  as part of its onResume activity lifecycle,  it sets a system property called persist.sys preventPowerKey  to a value of on.  And if this activity moves into the background  as part of its onPause activity lifecycle callback,  it sets the system property to off.  And to actually execute commands in the context  of this app, the persist.sys preventPowerKey system  property needs to have a value of on.  And FQC app cannot have a foreground activity, which  it checks before executing a command.  So the way we achieve this is we crash the app  while that activity is in the foreground.  So we send a broadcast intent to FQC broadcast receiver  with a null action string, which at runtime,  the application does not check to see whether this action  string is null.  It operates on it and encounters a null pointer exception.  And this sets the requirements where  we have the system property to the desired value.  And there are no activity components  of the FQC app in the foreground,  which the FQC service checks before it  will execute a command.  So then we send it an intent with the command  we want to execute in the turnOffHeater string extra.  And executing commands in the context of a system UID app  is very powerful.  This is a very limited set of capabilities.  You can grant arbitrary permissions to apps.  You can install apps and then grant them the permissions.  You can perform a factory reset.  You can record the device's screen from the background.  You can drive the GUI by injecting arbitrary input  events and then also perform operations with app ops.  So here we have a demo.  We have BadApp, which is going to install an app programmatically  using this vulnerability called AllPerms  and then grant it all permissions available  to a third party application.  And this is on the track phone BlueView2.  Just going to the app info, showing that this application  does not have any permissions.  We're going to run it, start that activity, crash it,  and then interact with the FQC service in the background  to install an app.  And then grant it all the permissions  available to a third party app.  So there it is, AllPerms going to its permissions.  This shows kind of the course view of the permissions it has.  And then moving to the more granular,  you can see that this has quite a few permissions, which  could be abused to surveil the user.  Thank you.  So the best we can tell, this Evenwell Digitech company  that created the app, they're a Taiwanese company.  They have an app on Google Play, a test app.  And this used to be on Nokia devices, which  were on Android S. And then they moved to Android S.  And then they moved to Android S.  And then they moved to Android S.  Which were on Android N and Android O, or Nougat and Oreo  7 and 8.  And then they removed it in Android 9 or Android Pie  due to a battery issue.  And then looking at honhai.com, there's  a PDF there that shows the ownership of this Evenwell  Digitech Inc. Company, which it's owned by Foxconn.  So here's another application that  exposes the same vulnerability, exposes  local arbitrary command execution as a system  user to co-located apps.  Again, you just need a local app that hasn't been granted  or doesn't request any permissions.  The vulnerable device is the iTel Vision 3 Turbo.  It's an unlocked device.  The package name is com.transion.autotestfactory.  You see the file path, it's factory.apk.  The version name, version code, and runs as a system UID.  And in this workflow, the malicious app  needs a file system location that's  both readable and writable to the malicious app  and the factory app.  So it takes its base scope storage directory,  makes it globally readable, writable, and executable.  It then creates a shell script in this directory  with whatever commands it wants to execute,  makes it globally readable and executable.  And then it creates another file.  It needs a specific file name that's  expected by the factory app, runscriptfile.txt.  And in this app, it essentially just runs our shell script  in a shell that was from step two,  makes this file globally readable and executable.  It then interacts with a broadcast receiver component  named command receiver.  And it sends the file path to the runscript file.  And then the factory app in the command receiver,  it reads the contents of that file, which executes a script.  And then it writes it to shared preferences.  The command receiver then starts monkey background service,  which then reads from shared preferences  and executes the script with system privileges.  Next, we're going to talk about some ZTE-specific  vulnerabilities.  There's three of them that we discovered.  The most severe is the first one,  which is an arbitrary file write as the Android system, which  is system server.  If you're familiar with Android, this is the Android framework.  This is what most applications request functionality and data  from.  And the way this is accomplished is by a zip file  that employs relative paths using path traversal attacks.  There's also another vulnerability  where you can start arbitrary activity components  in the context of a system UI app, where all the intent  fields are externally controlled except for the action string.  And then lastly, there's a vulnerability  where you can delete arbitrary files.  There's a vulnerability where you  can delete arbitrary files or delete directories recursively  in the context of the settings app, which  runs with a system UID.  And all three of these vulnerabilities  do not require any permissions, except the last one checks  to see that you have one of four different package  names where none of these package  names are actually installed.  So you can boot up Android Studio  and create an application with whatever package  name you want to fulfill this.  And it doesn't check the actual app signatures.  It's just checking the package name, which obviously is not  secure.  So this is from ZTE's security bulletin  showing the impacted devices, up to what version is impacted,  and as well as the software version that it was fixed in.  So this is the workflow.  We have a local malicious application.  It creates an AndroidX file provider.  And it just needs a URI authority  that starts with com.zte.beautify,  because system server checks with strings starts with,  instead of strings equals, which is obviously  more discriminating.  So we just create an example URI authority of com.zte.beautify  underscore potatoes.  And the malicious app then, in its assets directory,  like within the application, it then  unpacks a zip file to its internal storage  into a directory that is shareable by its file provider.  It then grants system server, which  has a package name of Android, read access to this zip file  that it just unpacked using the standard API  from the context class called grant URI permission.  It then broadcasts an intent with an action string  of com.zte theme change with the URI  to this zip file, which is employing path traversal  attacks using an extra named theme underscore URI.  And theme ID can be any arbitrary string.  System server then unpacks this zip file,  which we granted it read access to.  It doesn't enforce any constraints  on any of the file types or file names.  It also doesn't protect against any of the path traversal  attacks.  It doesn't canonicalize the path and enforce any constraints  there.  So it essentially just, in its context,  executing a system UID as the Android framework itself  overwrites files.  And in certain cases, depending on what is overwritten,  a third party application can cause a system crash just  by an uncaught exception in the system server process  to trigger initialization routines.  Say if you did overwrite another application  or overwrite the screen lock database  with a screen lock database copy that does not  require any pin or pattern.  So here are just some of the use cases.  You can uninstall apps.  You can overwrite applications.  You can overwrite app libraries.  You can overwrite the screen lock,  which will work once after you perform a system reboot.  And at the bottom, you can see the crafted zip file.  It's called notevil.zip.  And as you can see, it's using relative paths, which  move up the file system.  And then overwrite the lock settings database as well  as its journal file.  So here we have a video from the ZTE Axon 40  showing that we have a screen lock.  And this is done with another phone  just because we have to do a system crash  and to show it in one take.  So we just showed that we have some pictures there.  This is the attack application showing  that it has no permissions.  So now we start an arbitrary component, perform a phone  call.  We don't have service on this device.  We delete the user's photos.  And then we're going to start WhatsApp,  showing it's the official legitimate version of WhatsApp.  Then we go back to the POC app.  We overwrite the screen lock database as well as WhatsApp  with a repackaged version.  The repackaged version caused a system crash.  Now it's going to boot up, showing that the device no  longer has a screen lock.  So there was no screen lock there.  We open up the photos.  User's photos are gone.  And now we run WhatsApp, which is our own version, which  is just kind of a silly version.  But if we wanted to be malicious,  we could have a repackaged version of WhatsApp  that appears to be WhatsApp that gets the user's data  surreptitiously and sends it off.  And so just to summarize, looking  at some of these vulnerabilities,  some of the root causes, there's definitely some failure  to perform access control at application component  boundaries, at interfaces, on network sockets.  Also, when you are unzipping a zip file,  you certainly want to canonicalize the path  and enforce some constraints.  In Android 14 applications that target Android 14,  there are some platform defenses which  are going to prevent escaping using relative paths.  And if you try and protect your application  component with a permission, and this permission  isn't declared anywhere, it obviously  doesn't provide any protection.  And in many cases, we saw a lack of a whitelist, which  could at least kind of constrain what a user could do  and limit the impact instead of having  it be completely unbounded.  And also relying on just the package name of an application  doesn't provide you with any real security.  As I mentioned earlier, you can use Android Studio  and create any arbitrary activity or arbitrary app  with whatever package name you wanted.  And just some suggestions.  So vendors could use some showing,  looking at these vulnerabilities,  some sort of proactive scanning of devices  before they reach the user.  Also maybe some sort of certification  showing that the device has undergone  some sort of security analysis.  Enterprises need to constantly monitor and regularly  scan assets in order to enforce security policies.  The user, if you see some of these pre-installed  applications, you may want to disable them.  And if there is a pre-installed application that's  vulnerable to arbitrary command injection,  if you execute that command, you can have the application  disable itself to kind of close that vulnerability.  And the way we find these vulnerabilities  is a firmware pipeline where you can run a firmware image  or a set of applications, run it through some static analysis  engines, looking for violations using vulnerability patterns,  applying some filters to it, and then creating POC.  And after introducing all these vulnerabilities,  Quokka has an application called Q-Scout,  which you can download for free and run it on your device  to see if your device is impacted  by any of these vulnerabilities.  And the QR code takes you to the Google Play link  to download the application.  And just to wrap it up, so third-party applications,  even though they may appear limited,  they can interact with their environment looking  for insecure interfaces of privileged pre-installed  software.  And any time you have some software and it goes out there,  I mean, you should assume that people are going to spend copious amounts  of time reverse engineering your software, looking for software flaws.  And as shown by this presentation, privileged pre-loaded software  could use some increased security vetting.  And you should read our paper.  It goes into much more detail, has POC code.  It's about 70 pages.  And you can contact us at oem at quokka.io.  Try the Q-Scout app to see if your device is vulnerable.  And if you would like to continue the conversation,  we'll be at Yardhouse at Lync at 1.30 today.  And that's all for the presentation.  I'd like to thank you for attending.  And it looks like we have two minutes, maybe.  I don't know if that's enough for questions, but if there are.  Of those, the Blade X1 from Visible, it didn't have any of those vulnerabilities.  It was actually part of the data set, but didn't contain any vulnerabilities.  If you were limiting it to that set of devices, yes.  All right, well, if there's no more questions,  thank you very much for attending the talk.  Thank you.


url: https://www.youtube.com/watch?v=8Ng91UY3D2M
title: DEF CON 31 - Spread Spectrum techniques for anti drone evasion David Melendez, Gabriela Garcia
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=8Ng91UY3D2M",
    "title": "DEF CON 31 - Spread Spectrum techniques for anti drone evasion David Melendez, Gabriela Garcia",
    "description": "The popularity of cheap and DIY drones has made them a target for attackers using radiofrequency (RF) signals. Frequency hopping is a technique that can be used to mitigate the risks associated with RF warfare. However, implementing frequency hopping in cheap and DIY drones presents several technical challenges, such as the need for a stable clock and synchronization between the transmitter and receiver without rising hardware costs. Despite these challenges, frequency hopping can significantly enhance the security of consumer and DIY drones making much more challenging or even useless anti-drone systems' role.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2486,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   Good morning, everyone.  We deeply appreciate you, oops,  collecting our session amidst the array  of impressive presentations happening  concurrently in other tracks.  And today we'll delve into the pivotal role  that SDR plays in the real world's military drones.  Let's now turn to my colleague, David,  who will lead us further in this topic.  So, we are Gabriela Garcia and David Melendez.  In that case, Gabriela, a.k.a.  Gaps, it's the first time in DEF CON for her.  And she's a security developer and a hacker  and a hacking community organizer.  She's also a coding and cyber security instructor and mentor.  And she's helping me to present this presentation  because my English is from Zaragoza, Spain.  So, she's attending several conferences,  like Code Motion, GS Day in Canarias.  It's a good place to go to the beach.  And in my case, it's not my first time at DEF CON,  but it's like this with Shoot the Noob.  I am still processing the Jack Daniels, maybe.  So, it's not my first time in DEF CON,  also in several places, like the most famous conference  in Spain, like RouterCon.  And I am a book author about drones, Hacking with Drones.  It's a very original name.  And just to show how old I am, I am very a fan of Capo's Party.  So, Gaps, let's go.  Okay, the context.  As some of you may have accidentally heard,  we are in a wartime context.  There is currently an alarming high number of conflicts  occurring around the globe.  And military equipment manufacturers  emphasize in one primary objective,  which is to minimize casualties.  This is where drones take on particular significance  as an instrument of warfare.  Um, next.  Okay.  Drones.  Sorry?  Yeah, let's go.  Drones have evolved into essential instruments of warfare  due to various factors.  They enable precision strikes in combat,  they eliminate the need for on-board personnel,  and they are perfectly suited for symmetrical warfare  and are crucial in executing tactics and strategies  for real-time covert operations.  Drones, as a precision-guided weapon,  offer numerous advantages.  They ensure greater accuracy in attacks,  resulting in reduced collateral damage  and fewer civilian casualties.  They minimize human risk as they are remotely operated,  and their operational duration is extended  since there's no concern for fatigue.  Additionally, their versatility is showcased  by the capability to be equipped  by a rank of weaponry from missiles to bombs.  In symmetrical warfare, drones offer cost-effectiveness  when compared to traditional manned aircraft,  and this is evident through cost reductions  in drone production methods such as cardboard drones,  wooden drones, 3D printing,  and the use of affordable chipsets.  In strategic terms, drones offer tools for real-time  covert operation and tactics,  and additionally, they enhance surveillance capabilities  and in data collection and intelligence purposes.  Drones also serve as a powerful asset for SIGINT,  given their ability to gather information, intercept,  and analyze enemy communication and electronic signals.  They can access challenging regions,  operate continuously for extended periods,  and transmit data in real-time for prompt threat response.  Furthermore, they can execute covert missions  for high altitudes or using discrete flight patterns.  Some prevalent anti-drone measures  include utilizing both thermals and standard cameras  for shape recognition,  detecting heat emissions for engines and electronics,  analyzing distinct drone noise characteristics,  employing radio frequency and waveform detection,  and identifying unique radio signatures.  To counteract detection measures,  operators employ several strategies  like using frequency hopping,  engaging jammers that operate on unconventional frequencies,  implement robust communication protocols, and so much more.  But it's important to highlight that,  regardless of the advancement,  no drone can effectively withstand  a direct physical attack like a gunshot or a stun.  Okay, guys. Thank you.  So, I want to talk about this type of drone,  drones as war elements.  So, we're going to start...  Well, excuse me.  The use of drones for seeing signals,  they are used to collect information,  extend reach to hard access areas,  provide operations, real-time transmissions,  as Gav said,  and covert operations for high altitudes  and discrete flight patterns.  So, the typical anti-drone measures  they are distributed to thermal and standard cameras  for shape detector.  So, you detect the drones as the shape of the drone.  It's like a drone. It must be a drone.  So, detecting the heat of the electronics,  especially the motors.  So, you see four spots, four heat spots in the sky.  Maybe it's not a pigeon, so it's a drone.  So, using artificial intelligence  or natural intelligence, maybe.  So, you can detect those drones simply by seeing them  or by sight or by cameras.  Another technique is characterization of drone noise.  It's like, if it sounds like brr, it's a drone.  But it's, you know.  Also, the most typical way to detect a drone  is by radio frequency and wave form detection.  So, we have here the most important way to detect a drone  and the most cheap also.  Just because most drones work with Wi-Fi devices,  Wi-Fi communications.  And if we have a Wi-Fi detector, it's not very expensive.  So, we have to detect the drones by Wi-Fi characterization.  So, most of the drones nowadays  have the capability to transmit through Wi-Fi  or 2.4 gigahertz on five.  So, it's very easy to detect a drone with this method.  And the last one is radio signature using SDR devices  with the typical waterfall that we're going to see.  So, in last DEF CON, I talked about this topic.  And the topic is the same as the last one.  So, the countermeasures are very, very, it's the same.  It's the frequency hoping and the unexpected frequencies.  So, typically, police devices, state force devices,  tries to jam the signal of the drones with jammers using  the same fixed frequencies.  They are the typical Wi-Fi jammer and the 5 gigahertz  jammer.  They are very constrained to that frequencies.  And the last one is the most funny.  Yes, shoot the drone, right?  It's the best one, but it's the more expensive one.  And it's not very subtle.  I want to explain the evolution of the Atropos.  If you play StarCraft II, as I am,  you will not know that's the Banshee.  Atropos is Banshee in Spanish.  So, I am original, right?  I know.  Yeah.  The Atropos is a very, very old drone  that I made like a decade ago, more than a decade.  I was young.  I was in my 20s.  Just to notice that I am not still in my 20s, so.  Well, it's a homemade quadcopter with a Wi-Fi router.  It was made when the Raspberry Pi didn't exist, luckily.  And when the Arduino was starting.  So, I use a microcontroller from a microchip, the PIC,  for generating the power UDM signals to the motors.  And the stabilization unit is from a Y9 chuck and Motium Plus  from Nintendo.  So, they are glued inside the drone without the case,  obviously.  So, I use the web page of the router as a telemetry control.  For control and telemetry of the drone, I've used that method.  So, the first approach to control the drone  was indeed Wi-Fi.  So, the first attack I suffered in a conference  was the authentication attack a long time ago.  So, we are here from that.  As years passed, I was equipped the drone  with several tools, like WPS attack with Bully,  with extra onboard hardware, and so on.  So, the first approach with this drone  is to avoid the authentication attacks using beacon frames.  That was the first approximation.  So, just another functionality was  to inspect all the frames, all the beacon frames  of the environment.  So, just for a second.  And to jump for distraction, so I've  generated a lot of frames of fake drones  just to hide the right one.  So, the evolution of the Atropos was the state two.  So, I decided to make another drone called Interceptor that  was presented here at DEFCON.  And maybe I was tired to travel with a big drone  around the airport.  So, I decided to make a tiny drone like this,  just with the same system, with the same beacon system,  with the same beacon system to transmit the commands.  So, the last approximation that I made with this drone  was to use FM radio to send the commands to the drone,  just to hide, as a method, to hide the communications  from the jammers.  So, it was not enough for me and for us.  So, that was the first approximation.  I have a USB trainer.  It's not a drone command.  It's too expensive.  So, I decided to put a USB router to that trainer  and to connect throughout the standard Wi-Fi.  That was the first approximation.  The second one was to send four beacon frames  from one router to another.  So, and the authentication attack was not possible here.  So, that was the second approach.  But I'm still vulnerable to jamming Wi-Fi attacks.  Well, the third approximation was with the Interceptor.  It has a two-way communication.  I am able to send the commands and receive telemetry  from the drone using the same system.  That was the last one, to a redundant system  with FM everyday payload.  This is used to, for example, with the Raspberry Pi,  maybe you know that there's a project  that they use a one pin to generate FM radio.  So, you are able to create your own radio station  with its own name.  So, in the name of the radio station,  it travels the USB commands to the drone.  So, you can see the talk.  Well, there are several experiments  with the Interceptor.  That was the RBS FM, and I used the RBS part.  So, the right one.  The audio, the mono audio and the stereo audio  just was for fun.  So, we reached the stage three to the World Weapon.  So, the last approach was to control the drone  through arbitrary frequency generation.  So, how can we do that?  We generate a custom frequency.  So, the drone receives that frequency  throughout SDR, so well-defined radio.  So, and the last one, I am able to change the frequency  dynamically from the transmitter to the receiver.  So, this is the current approach.  I use a B-Core 2.  It's a tiny board of open WLT.  So, I use the USB with the same method.  So, I generate through I2S bus to ASK modulation.  I'm going to explain that.  So, with SDR dongle on board the drone,  I can receive that command in an arbitrary frequency.  So, no police, guns works with this.  So, what is a spectrum?  A spectrum is a modulation that I  am able to change the frequency very fast to disturb  any method to receive a jammer.  So, the jammer doesn't know what's the next frequency  that I'm going to use.  So, the jammer is useless in this case.  May I use the kid's explanation?  Excuse me?  Spread spectrum is a modulation technique  that broadens the signal across a frequency band much wider  than the original information requires.  By employing spread spectrum, resistance to noise  and interference is enhanced.  This is because the signal is spread over a broader spectrum  and can more effectively manage noise concentrated  at a particular frequency.  There's two key terms inside the spread spectrum.  First, the FHSS, which stands for frequency  hopping spread spectrum.  And second, DSSS, an acronym from direct sequence  spread spectrum.  We credit the remarkable innovation of the spread  spectrum to Heidi Lammer, not just a Hollywood actress,  but also a brilliant inventor, in collaboration  with George Antheil, that pioneered  spread spectrum system.  Contrary to popular belief, while Lammer didn't invent Wi-Fi,  their work laid the groundwork for today's Wi-Fi, CDMA,  and Bluetooth technology.  Go ahead.  So the frequency hopping spread spectrum  is the technique that we use here.  So we generate the signal by toggling a general purpose  input-output pin of the B-Core.  That this is more of the I2S bus.  So if we toggle the pin very fast,  we can generate a radio signal.  If we solder a wire in that pin, we have an antenna.  So you have a round modulation of that signal.  So if you change the frequency of that toggling,  you can transmit in an arbitrary frequency  to control the drone.  So this technique uses the frequency hopping spread  spectrum.  So I transmit a message with a given frequency,  and the next message is transmitted  with another frequency.  That is arbitrary.  It's pre-established between the transmitter and the receiver.  So this is a combination of techniques,  starting from, have you heard about Tempest?  So this is the same technique, but changing the frequency  constantly.  So would it be possible with a $15 board instead  of a Raspberry Pi, like the MT7628 chipset?  Maybe.  Hold my beer.  So what is the I2C bus?  The I2C bus, it's not the I2S bus, excuse me.  It's not the I2C bus.  The I2S bus is used to transmit and receive digital audio,  but we are not using this bus for that here.  So we have two wires.  One wire is a clock pin, and we have a data transmission  and a data receiving.  We are not to use the receiving data,  so we only use the clock pin for the moment.  So what is the clock pin?  The only one that is toggling constantly.  So this is the method.  Well, if we see the data sheet of the MediaTek MT7628,  we see what address we found the device, the I2S device.  So we can write directly to the registers  to turn on and off the clock pin.  So this is the clock plan of the SOC.  We have a primary clock, and we can  lower the frequency of that pin by configuring the clock  dividers.  So by configuring the clock dividers,  we are able to change the frequency constantly  and seamlessly.  So we have to set up our I2S device  like we are with a new driver.  So with this project, it's a new driver to the I2S device  for this chipset that enables the I2C bus.  But what I'm doing here is I'm not  What I'm doing here is to enable and disable the clock constantly  to generate a high level and low level modulation.  And when I want to change the frequency,  so I change the last one, the deep config and deep config.  So we can choose a very wide set of frequencies.  So if I turn on the clock, I am transmitting in a frequency  configured by the clock dividers.  So if I turn on, I'm transmitting that frequency.  And if I turn off, I'm not transmitting.  So the most simple modulation is to amplitude shift gauging.  It's the same like garage doors, remotes, and so on.  But here, I'm creating the modulation just turning on  and down the clock of the bus.  So if I want to transmit 1, 0, 1, 1, 0,  I want to turn on and off the clock.  And I'm giving frequency.  So how to receive that?  In the drone side, we can use our SDR USB  to receive that modulation.  So if we tune the SDR in that frequency,  we received each packet like we see each packet  like a high blue bar.  So that's one command of the transmitter  transmitting to the drone.  So this is the raw command seen by amplitude  as the receiver receives that packet.  So we have a preamble here just to tell the receiver  that this is a valid packet.  So the receiver starts recording all the IQ values from SDR.  And it decodes if it's in the high level or low level  to decode the binary transmission.  So how it works, it's an extra board of the drone  that accepts bit stream from the device from the file system.  So it modulates 2SK, and the ads, and CRC8 by two timers.  I have two timers here.  One timer is triggered every packet.  And the other one is triggered in every symbol.  So we have one timer, up, down, up, down, up, down, up, down.  On each symbol, and I have a timer, up, down, up, down,  on each packet.  So I can transmit the symbols in a very specific time,  and every symbol in a very specific time.  So the receiver is another big core  attached to an SDR dongle that it receives.  In that frequency, all the data from the SDR.  And how I did it by Frankenstein?  Well, this is made entirely in C. No Python here, sorry.  So to receive the data, I change the frequency constantly  to receive the commands.  So I have to use the libisdr library that  is the same that use RTLS, TCP, and so on.  So I have to make my own program.  I have to program my own driver to transmit,  and I have to do my own program to receive.  So in this approximation, I have a list of frequencies.  So the transmitter transmits one packet in one frequency  and changes it to the next frequency.  So the receiver has to synchronize,  has to find the first packet in a given frequency.  So if both sides have the list of the frequencies,  the receiver knows what step in the list of the frequencies  is currently.  So the receiver is able to continue  to change the frequency, taking account of that list.  So for this setup, I decide to make our own transmitter.  This is a PCB board with a custom controller,  so with the typical two joysticks of the drone.  So using the VCO, I have to make a new transmitter.  VCO, we attach a linear amplifier  to make so much more noise that makes the VCO itself.  So this is the transmitter.  So this part is the antenna attached to the I2S GPOs.  That is a peak.  So how we generate?  Well, as you see, I can transmit in a very wide range  of frequencies.  I make this demo in my house in Spain,  because as you see, I'm transmitting  with the frequency military air.  So if I go to prison, I like to go to the Spanish prison  just to let my mom to bring me cigarettes.  So if you see that, this is the difference  between the VCO without the amplifier  and with the amplifier.  So there is a big difference, right?  It's up and down, it's one packet, right?  And as you see, if I zoom out, as you see,  I'm transmitting in a very wide range of frequencies.  As you see, I'm transmitting.  Let's see again.  Well, you see two signals here, because the spread spectrum  is transmitting in that frequency  and this changing to a neighbor frequency.  This is a demo just to demonstrate  that the transmitter jumps from one frequency to another.  Well, I am able to jump in a very wide range of frequencies  that they are very far from each other.  So from a jammer, this is an enigma.  Indeed, we can skip the frequency hopping technique  and simply transmitting with a fixed frequency,  but unexpected by the jammers.  So it's much more reliable and the transmitter  doesn't have to jump from one frequency to another,  but because it takes time for the chip,  the SDR dongle is very cheap, $20.  And it takes time to change the tuning frequency  from one frequency to another.  So we can use simply this frequency  and almost no jammer will take care about this,  because what about I'm transmitting  in military frequency and the jammer  tries to jam my own drone, jamming, indeed,  military frequencies, right?  This is the web page of the drone.  So I'm still using a Wi-Fi transmission  as a primary method.  So I use this modulation as a fallback.  So the receiver decides which command to use.  If the receiver receives a Wi-Fi command, it uses them.  But if the Wi-Fi doesn't work, the receiver  uses the alternative method.  So the last one is to demonstrate  that the drone flies, indeed.  Please don't kill anyone.  Please, please don't kill anyone.  So maybe I'm not allowed to fly the drone here, sadly.  I don't know what, but the drone killed very few people.  Like only three people.  As you see, it's an outside drone.  It's not an inside drone.  But let's make a little noise, right?  Just to make noise.  We come from Spain, so any of you have a code to boo?  Well, it isn't that it is too far.  It's not that it's too far.  Well, it's jumping.  If you slow motion the video, you can see it flying.  But seriously, guys, I know what I'm doing, not flying it.  So we are fine with the time?  OK.  So thank you for coming here.  And if you have any questions, we will be glad to answer it.  Thank you very much.  .


url: https://www.youtube.com/watch?v=7oAZK8x_mL0
title: DEF CON 31 - Spooky Authentication at a Distance - Tamas Jos
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=7oAZK8x_mL0",
    "title": "DEF CON 31 - Spooky Authentication at a Distance - Tamas Jos",
    "description": "Spooky authentication at a distance outlines a new and innovative post-exploitation technique to proxy common authentication protocols used in Windows environments remotely and with no elevated privileges required. This allows security professionals to perform complete impersonation of the target user on their own machine without executing any further code on the target machine besides the agent itself. This talk will also demonstrate the applicability of this new technique by performing no-interaction, full domain takeover using a malicious peripheral in a simulated restricted environment.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2701,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   Thank you everybody. Excuse the profanities in advance and let's get started. So the title of my  talk is Spooky Authentication at a Distance AKA Why I Don't Care About Your Passwords. So  let's start about me. I have a day job and a night job. I'm working in two shifts. Day job is  at a boutique pen test company called SecConsult. We are mostly prevalent in Europe and Asia.  Not much here in the states. And I am from the Swiss division. So I'm working at Switzerland. My  night job I run under the alias of ScalSec. I am an open source developer. I have a lot of open  source tools created over the years and published mostly under MIT license. And I'm a proud  member of Porchetta Industries for some of the audiences. And we have an awesome logo over  there. So the biggest project maybe that you might have heard of is PyPyCats. Anybody has heard  of PyPyCats? Anybody is using it? Nice. Thank you. And also I have a tendency of rewriting  libraries for my own abusement. So AIOSMB is basically in packet rewritten from scratch. MSLDAP  is like my own LDAP library and I have like Kerberos, NTLM, SSH, whatever. I'm a big fan of  networking protocols if one can tell. And all of these are open source except for Octopon.  Octopon is a special project and actually while developing Octopon I started looking a bit  into like nested things that one can do with Windows integrated authentication and hence this  talk was born. Also I like to just go and ramble about everything. So I have a promise for  you today or this afternoon. In this presentation you will see a novel technique that will  allow you to basically if you manage to execute code in a user context of machine A then from  machine B which is like your machine, the attacker machine, you will be able to perform  authentication in the context of user A but from your own target machine. This means that it  will basically the code, like the attacking code itself is going to be executed on your  machine and hopefully you haven't installed XDR or AV or whatever on your machine because  why would you? This will allow you to if you manage to sufficiently hide the proxy binary and  I will give you some hints on how you can do that. It's a really small proxy binary. Then you're  basically golden because you usually don't really necessarily care about the initial point  of compromise. So you don't really care about what is on the HR machine or the HR lady who  double clicked on the spam that you crafted. You are mostly caring about what is on the  servers and like over SMB or LDAP that you can reach using the HR person's authentication  context. So in summary I'm going to talk about first just a brief overview, like a really  gentle overview of Windows authentication protocol. This is going to be in a test tomorrow  so I hope that you are going to take notes. General description, we are going to use LDAP as  an example and I'm going to like take your hand and walk you through on how NTLM, Kerberos  plays together with SPnego and we are just going to skim over and I have 2 demos for you, not  live demos because they told me I'm not really allowed to plug in random USB sticks on this  machine. We are going to talk about SSPI and basically the how to authenticate locally but  remotely but also locally part. So Windows authentication protocols in a nutshell. Before  this first slide about authentication protocol, one thing that I want to mention is most of  the people that I talk with about authentication protocol, they have this weird notion that  like the authentication protocol basically stops being useful after you perform the  authentication itself and basically it's either a yes or no decision whether you get access to  the resource or not from the server. However I would like to point out and I'm going to point  it out multiple times that it is not the case because usually modern authentication  protocols also do key exchange and you will have to do something with the encryption and  decryption key context. So as I said there is going to be a lot of letters. No worries if you  cannot read it. It's actually quite readable. I was really afraid of this one. So basically we  take like a random network protocol, generic over you, client would like to log into the  server. How to do this? Like if you would be willing or if you wish to implement your own  custom protocol and you would like to have some authentication on it, then basically like  this is the generic run down how it should look like. So you would obviously want to have  some version negotiation between the client and the server because probably your protocol  is not going to come out right at the first time so you will need to have some versioning and  the client and the server should be using like the same version or the dialect of the  protocol. Oops, we are already at SMB, whatever. Yeah, so after the version has been  negotiated then you will see the authentication protocol negotiation. This can be in the  version negotiation as well. And then both the client and the server agreed on  authentication. Then I put it in a separate logical container. The authentication client  and the authentication server are going to initialize and usually everything that these two  generic like authentication concepts are willing to communicate with each other are just  going to be interposed on the actual network protocol. We are going to see it in great  detail later on. And this back and forth of the out messages are going to go until the  authentication either succeeds or not. Obviously like currently we are not touching the  authorization part because we don't have like a day of explaining every single bit of  information here. So after the authentication is finished then usually both the client or  the authentication client and the authentication server are going to end up with a shared  secret. And this shared secret is used or not used depending on what the protocol would  like to, like the actual network protocol would like to do in the future. They have the  option to use the shared secret to basically encrypt or protect the integrity of the  protocol. So moving on, this is a continuation of the slides before. So authentication  protocols, so encryption and decryption, user would like to list the shares for example.  It double clicks on or like it types like slash slash IP address because we are still in the  NTLM times and we don't want to use Kerberos anyhow. This is going to be translated inside  of the client to like a series of messages and these are plain text messages. So basically  the client can request the authentication protocol to encrypt the message. Then the  encrypted message is going to be dispatched to the server. The server is going to dispatch it  to the authentication protocol which does the decryption and or the integrity verification  and going to be like turtles all the way down from here. These encrypted and decrypted  calls are going to go on until the protocol terminates or like the network connection  terminates. So here as I was explaining, we are going to use LDAP as like a case study  because it supports like all the authentication protocols and more than that shows like the  generational weaknesses in I would say like in any single place but whatever. We are going  to see like what LDAP supports as authentication methods and how we can maybe proxify some  of these. Moving on. Yes, so LDAP has a Sicily authentication. How many of you are familiar  with the Sicily authentication in LDAP? Yeah, I'm not really seeing many hands around  here. So Sicily authentication is actually a raw NTLM authentication that has been like  forced inside of the LDAP protocol thanks to Microsoft because when they came up with this  whole NTLM stuff they wanted to like stuff it like literally everywhere and this is one of  the main reasons why we cannot really get rid of it. So basically what is happening here is  that like you can have like a root query before authentication that basically explain like  the version negotiation part. Then you have the bin request where you specify Sicily and if  you want to check it in Wireshark, this is the place where Wireshark fails basically. The  sector just fails because not because of security issues but because like it's just like  simply put a badly made protocol. Nobody is really using it except for nefarious reasons.  One might want to use it. Anyhow so bin request, bin response, NTLM client is going to kick  in. NTLM client like the LDAP client is going to ask the NTLM client hey like what is the  first structure that I need to send to the server so authentication can proceed and NTLM is  going to say that's like okay like let's negotiate. No that might be an issue there but  point is that NTLM has like basically 3 data structures. The authenticate, the challenge  and the negotiate. Yes okay then it's negotiate. Sorry about that. So basically like  NTLM messages are being interposed on top of the LDAP protocol passing them back and forth  until the authentication is finished and then you have a shared secret available and if  for example like LDAP integrity protection is enabled then this is the shared secret that is  going to be used for either encrypt and or integrity protect your LDAP messages in the  future. Okay so quick word about Espinego. Espinego is basically an authentication  protocol selector protocol. That's a tongue twister. That supports LDAP Kerberos, the other  type of Kerberos and potentially it could support other authentication protocols as sub  protocols but mostly like these are the like NTLM Kerberos are the 2 main ones that are  being used in normal day to day life. So Espinego itself does not provide authentication. It  is just a way for the client and the server to agree on an authentication protocol to be  used in the future and one of the tidbits is that Espinego has an added integrity  protection in itself. So basically it is to protect against downgrade attack like not  downgrade attacks depending on if you think like NTLM is more secure or less secure  than Kerberos but this integrity protection requires after the NTLM authentication  finished as the sub authentication module to use the secret key to sign the Espinego  packet that has been sent by the client from the server so it verifies that the client in  fact requested only NTLM authentication and not somebody was doing it, a man in the  middle and removing the Kerberos part from the request. So LDAP supports like these, the  following 3 main authentication protocol classes. One is called simple. The simple can  have plain which is like user and password. Obviously there is no integrity protection and  no like secret key exchange after that because you are literally sending the user name and  plain text password. There is also none which is we call anonymous bind. There is Sicily  which is like it still bugs me that it's still enabled everywhere and we have the SASL and  inside of the SASL you can find Espinego and GSS API and yeah the external one is really,  really interesting because basically the external one presumes that you have created like an  MTLS connection already to the LDAP server and the external does not provide any other  information. It just says hey I already authenticated to you but over TLS or SSL so please  like verify that one and since I'm verified then just let me in and this is really, really  useful if you are doing like ADCS attacks for example depending. So just a quick rundown on  how the LDAP SASL Espinego NTLM authentication works and I believe like this is going to be  the most complex one. I don't want to torture you further. So basically LDAP client kicks  in, connects to the server via TCP hopefully. There is some version negotiation with root  query. Espinego client kicks in. Espinego client is going to like instruct the LDAP client  to send basically the supported authentication protocols to the LDAP server. LDAP server is  going to kick in the Espinego server saying that hey I got a new client. This is what they  support. What should I reply? It should like the reply of the Espinego server is then  interposed onto the LDAP client and LDAP client relays it to the Espinego client and you  know you get the gist. You don't need to read it through. Maybe at home because there's  going to be a test tomorrow. So how Kerberos authentication works. If we are not talking  about mutual authentication for Kerberos then it's going to be really simple. The reason why  it is so simple is because like the actual Kerberos communication is not being shown on this  slide because like the complexity is on the other end. So basically LDAP is just basically  using Espinego to instruct the Kerberos client to request a ticket and then they just send  this ticket and this ticket already contains the shared secret. So let's talk about SMB encryption  decryption because it is a bit different than like Kerberos and normal NTLM. So Kerberos and  NTLM themselves provide encryption and decryption algorithms to be used which are specified  by RFC and NTLM encryption decryption RFC the errata is larger than the actual RFC. That  should tell you something but mostly like besides LDAP like not many other protocols are  actually taking advantage of NTLM encryption decryption. Probably because it's based on  RC4 but I don't know that part. So how SMB does it, however, is that SMB sets the  slide like it's really nice and cute that you are like defining your own RFC and your own  encryption and decryption methods but actually I am Microsoft. I don't really care about it.  So how about just give me the secret key and I'll deal with the rest. This is going to be  like super important later for us when we are actually trying to rebuild some authentication  context on our own machines. So Microsoft has this SSPI. SSPI is a set of APIs that allows  you to interface with Lsys in a programmatical way and SSPI is basically created because as  some of you might know Lsys caches some credentials. I don't know if it's a big secret or  not but yeah it caches some credentials like sometimes plain text, sometimes not really  plain text credentials but they are there. The reason why they are there is because you have  like a million processes running on your computer in a Windows domain environment and these  processes want to connect to the DC or to some other servers and yeah it's not really nice  if we ping the user every time when a random background process wishes to authenticate to  the DC just to get the credentials every single time. So SSPI is the way that like a user  land application or a user land process would perform like an authentication either with or  without the user consent or yeah they don't really care about consent in this part but  there is a way to set it up that it prompts the user but like why would you do that?  If you are on the attacker side of course. So SSPI defines a kind of handful of API calls but  for the sake of this discussion we only need to take five into account. Acquire credential  handle, initialize security context, query context attributes, encrypt and decrypt  message. This is how we roll. If you have like a legit or an illegit process then this is  only the five that you would need to implement to get the authentication action rolling.  So again generalization, how it looks like. So basically client would like to authenticate  to the server. So client on its own end is going to first invoke acquire credential handle  that is going to create like an authentication context like on the LSS level. Then for every  single like authentication message that needs to be passed between the client and the  server, the client is going to constantly invoke the initialize security context part. Up  till to the point where the initialize security context actually from the client part comes  back to the network client and says like okay we are finished and like I believe that we have  like a good go at this authentication part. So if the result is okay then there is going to be  a shared secret like the shared secret that we were explaining in the general overview. This  shared secret however is going to be kept in the LSS process or something like no it's  probably in the LSS process. And then there is a problem. So far so good because like you  are not an administrator or some high integrity process so you cannot get out these keys.  However, there is actually an API call because what happens if for example in SMB's case,  SMB decides to implement their own encryption and decryption algorithms and they would  need to have the key for that. Like the shared key. What happens if like some like my process  would like to have that as well. So therefore we have the shared key that is going to be  query context attributes API call which you can invoke after the authentication has  finished successfully. And the query context attribute like this API, I'm not going to say  it again, is actually there to query like a lot of different aspects of the current  authentication context and one of these aspects is to actually give you back the secret key  like the shared key that has been generated based on like either Kerberos or NTLM or  whatever. And this is super useful for us actually because yeah, almost. So this is super  useful for us because what we can do here is that now like we can like from our machine can  instruct LSS to perform authentication for us. So authentication is done. What we need is  the secret key and we can now request LSS to give us the secret key. Well, what happens if  like can we do it remotely? I mean like it's just like four API calls. So like if you build  like an RPC that is wrapping these four or five API calls, then you should be golden, right?  Now, there is kind of a problem because there is a special case that like Kerberos  mutual authentication. In Kerberos mutual authentication, you will need to have like in  any way, sorry, you will need to have not just the secret key but also the IV. But how are  you going to get the IV? The query context attributes API does not tell you the IV at all.  And in normal situations like in NTLM, you don't need the IV because it's RC4. So why would  you need an IV? For Kerberos case, the IV, if it's not mutual, then you can read it out from  the ticket itself. But if it's a mutual authentication, that means that like the actual  client and the server are going to do like another round trip of exchanging tickets. Then  the session key, like the ticket that finally you end up with in the client is going to  contain the IV but you cannot decrypt that part of the ticket that contains the IV. And  also it doesn't give you that. So this gave me a bit of like a hard time to figure out. But  then it clicked on me. Basically, we have the encrypt message and decrypt message. So  taking the encrypt message is going to wrap our data, whatever data that we are encrypting  in a token. And that token must have the current initialization vector. Otherwise like  the other side would not be able to decrypt it, right? So this was the missing piece of the  puzzle. Now we have basically, we can make LSAS authenticate. We can have the initialization  vector and we can have the secret key as well. So your LSAS but on my machine. The goal is  basically to create wrappers for these four API calls. Sorry, five API calls. And that is the  easy part. The hard part is that now you have two choices. Now you either need to modify your  own attacking machine's LSAS process to interface with this, to be leveraging this newly  created RPC or you would rewrite each and every single authentication protocol that you  want to deal with. And since I love authentication protocols, guess where I ended up. So it  took I would say like roughly two years. But yeah, so I came up with an authentication  library for Python that is used by all of my network implementations that leverages these  type of RPC calls. How does it look like? So again, you don't have to read it. Oh, it's  actually, okay. I kind of like how it turned out. Basically what you're seeing here is that  you can perform these RPC calls. I'm not going to go over each and every step because I don't  want to make this presentation one and a half hours long. The final part of this is, sorry,  yes. So basically what we were discussing before is that there are like two ways that you can do  the encryption decryption part. Because my first instinct since I could not get the IV out,  like I could not figure out how to get the IV, what I did is that's like for each and every  encrypt and decrypt message call, I was performing yet another set of RPC calls to inject back  the encrypted data from my machine back to the victim's machine and make the LSAS decrypt  this and send back the raw data. Now this is not really the, let's say it's not really a useful  solution because it just hogs the bandwidth. However, here what you have is that with the  previously explained get session key and then encrypt message with some random message and  unwrapping the response token, you can basically have the entire encryption and decryption  context back in your home machine from the victim's target machine. So I would like to show  you two use cases for it. Actually multiple use cases but like two which I have a demo for.  One is, how did it get here? Sorry. One is just basically the proof of concept code is  going to be executed in the victim's machine and then from another machine we are going to  perform an authentication to the main controller. Let's hope that the codec works this time.  I see the video here. Oh that's nice because now I have to look over here. So the attacker  machine is on top. It's a Ubuntu machine and the victim machine is on the bottom. And  then we are going to execute this proxy binary. This proxy binary currently is just like  listening on the port on the victim machine. Obviously this is not the way that you would do  it in a real life scenario. This is just for proof of concept sake. And on the target  machine what you see here is that basically we told the library, the SMB library, not to use  any like actual credentials but to use the user name, sorry the IP, like the RPC server,  on the IP address and port of the victim machine. And as soon as basically I executed the,  like I gave the instruction. Let's just go back to the URL quickly if we can. So on top  basically that is the only information that the SMB client is using. So we have the IP  address of the target machine two times basically because, no just one time sorry. And the  port is by default it's set to something. It doesn't really matter. So the point is SMB  connection is going to basically work immediately and we can, oops, yeah, sorry, we can  perform an authentication here. Thank you.  So, yeah, it's just like I deliberately printed out all the debug data so we can see what  is happening there. And for the other protocol is basic, oops, sorry, going back there. So  just to show that it actually works so like it lists the shares and I can, like we can  actually download the file from the destination. Yes. So that was for SMB and we have one  for LDAP as well. And that should be coming soon. Yeah. Basically the command is exactly  the same and yeah, we logged in to the DC via LDAP. And here we are listing the SPN  like the Kerberos to the users for the time being. Okay. Sorry, I just need to speed it  up because time is of the essence. And we have it here. Okay. Yeah. That was the first  demo. So this was one use case. The second use case is that basically you can use this  technique by grabbing a Raspberry Pi like a single one. You can make it a USB dongle. You  can add some clever techniques to make it act as a keyboard like a rubber ducky for example.  And also to act as a USB Ethernet device. If you set up DHCP server, Wi-Fi access point,  whatever, then you can create a really, really neat attack tool with it. Because as we have seen  it in the previous slides, this technique does not require the attacker to know anything prior  about the target domain. If there is a user account that is actually active and the user has  executed this proxy library, then everything else can happen like all the authentication and  all the attacks are happening from another machine. Okay. And the basic domain  information can be pulled for example like the log on server or what not. And since all  users can pull information from the LDAP, then it just basically trickles down and you don't  need to add any, you don't need to, like if you have an embedded system, you don't need to  add any specific like target specific code. This means that like if you put everything  together in a small Raspberry Pi, which is kind of like on the desk for example, then what  you are going to end up with is like a pawn everything tool kit. Because if the proxy is  going to, is successfully executed and the way that it's being executed is that if you plug  it in, I'm just going to go on a ramble. So if you plug this device in, then it's going to  show itself to the target machine, an unlocked target machine. What it's going to show  itself is a keyboard like an HID keyboard and a USB internet device. With the HID keyboard,  your attacker code like just like with the rubber ducky, you control the key code. You can  instruct the machine to execute the binary like the proxy binary and the proxy binary is not  going to go out to the internet because you don't know if there is an internet or not on the  target machine. But what you know is that it has access to at least one network because you  provided this network to it via the Raspberry Pi. And then this proxy machine can connect  back to the Raspberry Pi and then whatever application is running inside of this Raspberry  Pi can immediately leverage the user authentication context of the target machine. So  basically like with some clever engineering, with this technique, you can do like upon all  Raspberry Pi that works on air gap networks as well. The target doesn't need to have any type  of access to the internet. So, demo. I'm going to show you how it works. I'm going to show you  how it works. Okay. This is the victim's machine. The victim's machine is currently just  like a, okay. The victim's machine is basically just a standard Windows 10 machine and  I have plugged in this device. Like you will have to believe me, I wanted to do it on the  stage but they told me that it's probably better to have video of everything. So, what are we  going to see now is that we have to wait until it boots and then virtual keyboard immediately  starts executing the code. The actual like reverse proxy binary is served via HTTP from  HTTP server of the Raspberry device as well. At this point what you would see is that the  proxy is executed and you will see two host names and port addresses. Those two host names  are the active directory server and over the LDAP port. It's too small. I'll be able to make  it bigger but no. Yeah. But this is not the point. The point comes afterwards. So, what we  can do is a bit of clever engineering. We can open the browser. Now, usually this is not  what you would do on the target machine. This is what you would do somewhere else. Where is  this somewhere else? Since I explained that the Raspberry Pi has a Wi-Fi like access point,  this service that I'm going to open. Oops. What happened? Oh, yeah. So, this service is  actually my Octopon project. I was explaining Octopon on area 41 like DEF CON Switzerland a  year ago. And this Octopon integrates this attack technique into it. So, I'm going to show  you the attack technique itself. So, what we are seeing here is that basically we already  have a lot of information available to us via the tool because between the time that the proxy  connected back to Octopon's like handler server and the time that I opened this, the automation  immediately started enumerating the domain. So, what we are seeing here is like there is  some SMB browser as well. So, like the SMB connection is working. There is no and there has  been absolutely no prior like user secret configured on this device. And we are going to  perform a Kerberos thing soon. So, we have this is the this part is the handler of the agent  like the reverse proxy agent. And currently like Kerberos thing is set as a separate entity.  So, I'm going to basically instruct the Kerberos logic to use the you already created session  that has been created by the proxy authentication to the target domain via the proxy library.  It will basically allow me to perform Kerberos thing on the target machine and then basically  like we have all the Kerberos tickets that we can send to hashcat to crack. And okay.  Tickets. Speed up a little. Who made this video? Okay. Yeah. And what is the  happening here on this session while we were Kerberos thing? It also started the domain  enumeration over LDAP and SMB which is basically not bloodhound but bloodhound. So, like I  basically I rewrote bloodhound in Python from scratch just for this. So, what we are going  to see here is that there's going to be a cut. And after the enumeration has finished, we  just like I'm listing here just like all the IP addresses and ports that the tool is  being that the tool is connecting to right now. And yeah. We did the SMB enumeration since  it's a virtual domain. There is not many there aren't many SMB hosts. And this is the  representation layer of the tool like my bloodhound implementation. It's called  projecto. And we can see that it's already like loading in the database that was  generated from the other session. And soon if it's loaded, what we are going to end up  with is a canvas. Hopefully. Any second now. Yes. Canvas. And then here are all the paths  to the domain administrator. After. Yes. Here you go. And this is fully automated.  Thank you. And yeah. I have some other slides as well. But this is basically the gist of  it. And I hope you have sorry. I hope you have some questions. So, I think we can oh, no.  Sorry. Really quickly I would like to do some shout outs. Hopefully the persons are inside  of this room. So, there is future research to be done with this one. Because I don't want  you people to be forced using my tools. Everything by the way except for the Octopon part  everything is going to be open source. It is actually already open source. I published it  yesterday. No, today. Afternoon. And the future of this research would be the to have  basically like all of those tools leveraging this type of technique which can be done. And  there was a gentleman hopefully he's here called Ethical Chaos. And a few years ago he  created a tool. And this tool is basically allows like it hooks every single like  processes on your like attacker machine. And overtakes the SSPI calls. Or like not just the  SSPI calls but like it could use to be overtaking the SSPI calls as well. This is some  modification needed. And it could be integrated like it could be used with this technique  that would allow basically like every already existing Windows process on your attacker  Windows machines, your PowerShell scripts, your SQL browser, whatever. To leverage this  technique. So, you don't have to deploy these scripts on the remote end. And it would be  really nice to do. However, I have my own platform. So, thank you very much. I already put  like a lot of time into this one. But if somebody would like to do it, then yes. Go for it.  Just hit me up. I can help if you need. The other shout out is that the other future  research that can be done is that there are a handful of other API calls that can be added  here to support PQ and other like Windows Hello like certificate based services to basically  use the exact same type of like authentication proxying. Which might be interesting.  Interesting, I am going to work on this part definitely. Because I know at least one person  who might be really interested in this. And yes. So, thank you for everybody who is on  these slides. Your research has helped me tremendously. And also here are the links with  all the like open source tools that you have seen here on this talk. The WS net dash dot net  is the actual proxy that has been used here. And QA time. If you have time.  Thank you.  There is a gentleman next to the camera. That I for sure see.  Well, I mean like currently no. Because it is like, I don't know the English name for it.  But like what this process does is similar to any other process that would use SSPI would be  doing. So, like there is no like nefarious running around here. Also like it's a fresh tool.  So, you know, like maybe in two hours it will be detected. I wouldn't know.  But I already implemented it in Rust and NIM. But I'm not going to provide that part.  So, any other questions? No? Thank you very much.


url: https://www.youtube.com/watch?v=NwnT15q_PS8
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
title:
  DEF CON 31 - SpamChannel - Spoofing Emails From 2M+ Domains & Virtually Becoming Satan - byt3bl33d3r

content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=NwnT15q_PS8",
    "title": "DEF CON 31 - SpamChannel - Spoofing Emails From 2M+ Domains & Virtually Becoming Satan - byt3bl33d3r",
    "description": "Ever wake up and ask yourself: \u201cDamn, how could I make email security suck even more today\u201d? Tired of your Red Teams phishing emails not landing in your targets inbox?\n\nDo you dislike Boston (the city) and love Satan?\n\nIf you answered yes to any of those questions you should come to this talk!\n\nI'll be showing you how to spoof emails from 2 million+ domains (while also \u201cbypassing\u201d SPF & DMARC!) by (ab)using a partnership between Cloudflare and the \u201cbiggest transactional email service\u201d on the interwebs. We'll be diving into \"edge\" serverless applications and the magical world of email security where everything is (still) held up by duct tape, pasta, and marinara sauce. Finally, I\u2019ll be dropping code and releasing a tool that demonstrates how to impersonate emails from 2million+ domains.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2242,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230917"
  }

  This text was transcribed using whisper model: large-v2

   Welcome. We're going to be talking about some email stuff today.  A couple of disclaimers. There's going to be a number of disclaimers throughout the talk.  First two, I tend to curse a lot during presentations. I'm going to try to curb it to an  absolute minimum, because I know it can be annoying. Number two is  I'm going to be going very fast throughout these slides, so just bear with me.  I have a lot of content. It was really hard to push this to 45  slides, to 80 slides in 45 minutes, but unfortunately  because of the timeline and everything, it was almost impossible.  Really quickly, who am I? My name is Marcello. I go by Bytebleeder a little bit  everywhere. I'm an open source developer, researcher, engineer. I like to call myself  an Infinity Stones teamer, because I collected all the colors.  And hey, fresh off the press, I'm looking for a new gig, so if you're hiring,  come grab me after the talk. Even if you're not hiring, you can come grab me after the talk and chat. I'm a friendly guy.  I like talking to people.  Third disclaimer, please don't do crimes.  This is going to be apparent while I'm saying this towards the end of the talk, but  you're just going to get in trouble.  Please don't. I know doing that here is like going to a heroin convention and asking  them not to do heroin, but just  please don't. How did this all get started? I just wanted to send an  email, albeit programmatically, through a Cloudflare worker.  If you're asking yourself why through a Cloudflare worker, it's because  I backed myself into a corner from a tech sack perspective. I had no other option.  I built this entire backend website using Cloudflare workers, because I wanted to be the hip  person using the latest stuff. And if you're not familiar with Cloudflare  workers, they're sort of akin to AWS Lambdas.  So it's a serverless computing platform. And it's a little bit edgy  though, in the sense that there's a twist to the Cloudflare solution, which  is they take your code and they distribute it automatically throughout their CDN, so it's always  like the person hitting your service is always latency optimized geographically  to where you're trying to hit the service. And you can also  only write them in JavaScript, TypeScript, and anything that emits WebAssembly, so  they're also slightly depressed as well, because they can only be living in  TypeScript land. This is  basically how you start out with Cloudflare workers.  You basically just run a command, creates a directory structure, then Cloudflare  provides a tool called Wrangler that automatically you can use  to manage and upload your Wrangler and your worker code.  And then your worker code is just automatically available at an HTTPS-enabled  URL that everybody can access. And the main takeaway here is that by  default, the worker code is public, because that's the whole point.  People want to access your service so they can use it, right?  So just for some context here, this is like  imagine 1 a.m., I'm just trying to work on this freaking website,  I want to go to bed so I can actually get to my day job. It's late,  maybe even a little drunk, and I just need  this website backend to send an email, right? So I'm just  drunkenly Googling, send email Cloudflare workers, and I stumbled  across this blog post from Cloudflare. It's like, send email using  workers with something called Mail Channels. I've never heard of whatever Mail Channels is, but at the time I didn't care.  Hey, it's got code. Great. Copy-paste this thing into my worker.  Works first try. And we'll go back to that code in a second.  It works first try, which in hindsight, red flag. Nothing really ever  works first try. But hey, I get an email, and it goes  to my spam inbox, which is somewhat normal, I think, because I didn't set up any  email security stuff, which I had very little about at the time.  So I leave this behind, come back a couple days later,  and I see that there was an open browser tab  throughout the gazillions that I had open from when I was working on this a couple days ago,  where there's this person asking on the Cloudflare community forum, saying, hey,  if I use this feature, this Mail Channels thing,  doesn't this allow anybody to impersonate my domain  and send emails from my domain? And I'm like, why, as the kids say, that's pretty  sus, right? Why are you even asking that? That's a weird question to be  asking just randomly out of the blue. And then there's a Mail Channels person in there  saying, yeah, this is just how the email works, though, so  there's nothing really you can do about it. Which, at this point, I'm completely nerd-sniped,  so I just keep Googling what's going on with this Mail Channels thing. I've never  heard of this before. And a bunch of people asking  a little bit all over the place, hey, can't people just impersonate my domain with this?  And I'm like, okay, what's going on? And then there's this guy on Reddit that's like, hey,  asks a really important question, because I didn't even think of this. Why is this free?  Why aren't you monetizing this? This seems weird. You're just allowing  people to send emails for free? And they're like, yeah, no, no, no, we don't care about  the money, right? We just care about sending an  email. It's fine. So they just went full Joker.  So I'm like, okay, let me just go back to the code that I just  in my sleepless stupor just copy-pasted into my worker code  and stare at this for a good two minutes. And for those  of you not TypeScript-inclined, first off, I envy you. Second off,  basically all this is doing is just sending an HTTP post request to some  Mail Channels API with the contents of the email that you want  to send. And if you stare at this for a while, you're like, wait a second,  there's no authentication here. There's no  username and passwords or API key in this shit. There's nothing.  So that's really weird. So I dig a little more.  And it turns out the Cloudflare and Mail Channels partnership  entailed Mail Channels creating this API, no auth required.  However, the twist is that it's only allowed listed at the network level  to Cloudflare SP space. So you'll only be able to hit this API if you come from a  Cloudflare IP. Well, anybody on the Internet can just create a Cloudflare account  for free and hit this API. So, you know,  just like connecting the dots at like 1 a.m. in the morning here, it's like, okay,  so is this like, I just need to create a Cloudflare account, which I already did. I just  uploaded the worker code, which I already did. And then you could just send emails through Mail Channels for real.  And yeah, that's basically how it works, which is really  weird. And then there was this other user in the same community forum, after all  the snarky comments, also asking the same issue about worker impersonation, which I still  don't understand at that point. And  the person's like, hey, so I created a Cloudflare worker that demonstrates this capability,  demonstrates this partnership between Cloudflare and Mail Channels. And it's just an HTML form  where you just put in the contents of the email. It's publicly  available. I blacked out the URL because I don't want you guys running  up this person's Cloudflare bill. But it's publicly available  and you just put in, oh, sorry, it's publicly available and you just put in  the content of the email and you just submit and you send  the email, which, okay. And I'm like, okay, for testing purposes, this is fantastic.  And I guess since I'm completely nerd sniped at this point, I'm just going to  what's the first three or four test cases that I can think of in order to possibly  figure out what these other people are talking about in terms of impersonation. So  test case number one, what happens if I just put a domain that doesn't exist  in the HTML form of the worker?  So I put in as a sender test.waterhogger.com, which is a domain that didn't  exist at the time. And I get an error back saying, hey,  failed to send email because the domain doesn't exist dummy, which, yeah, makes sense.  If this worked, that would be completely foobar, right?  And then how about a domain that does exist but I don't control? So as the sender,  then I put in test.example.com and it gives me back null.  Yay. I don't know what null means, but it turns out null means it works.  And I  got the email, right? But it goes to spam again, which is normal because I don't control  the domain. So I'm like, okay, this seems completely normal. What are these people talking about  with impersonation? And I don't know much about email security, but I look up the headers  and they're like, yeah, it's fail, soft fail, everything's bad, go back, whatever you're doing,  stop doing it. But test case three, I'm like, okay, what's the next  logical step? What happens out of sheer curiosity if I use a domain that  actually uses this thing called mail channels? Because I still don't know what the hell it is at this point,  right? So I just Google, okay, websites that use mail channels.  And at this point, I'm just thinking, you know, I've never heard of this. This must be  like some bottom of the barrel email service that maybe like your grandma used in the  1980s or something, right? Maybe like a thousand people use this, if not less.  Nope. Nope, nope, nope, nope, nope. So  two million somewhat domains, at least according to builtwith.com,  which is a site that aggregates technology that a bunch of websites use  and stuff. And this might be a little small there, but  there's a few heavy hitters in terms of people who use this  mail channel service. There's like boston.gov, there's notepad++.org,  which is really funny. And then everything else, though, is more like just  random ass websites that host everything and everything. And I really like builtwith.com  because if you were someone trying to target people, the filter  you know, mail channels, websites with estimated sales revenue over  one million dollars, just really just preem stuff right there.  Turns out I didn't even need to do this because mail channels also has a list of all their customers on the website.  Yay. So then I'm like, okay, so then  I go back to the worker and I put in like, you know, lobsters at boston.gov because  boston.gov was the one that popped out and, you know, go big or go home.  Yeah. And it goes straight to my inbox. No, doesn't pass go,  doesn't collect $200, just goes straight into my inbox. And on top of that,  if you take a look at the headers, SPF and DMARC both passed.  Okay. Just to be clear, at this point, I'm like, this is a worker  publicly available just on random on the internet that anyone can hit. They can just put in the details  of the email and they'll just be able to spoof any of these, those mains.  And then, so I try another, like how about minus at notepad++.org, right?  That's, yeah. So, and then  I try another, same deal, like goes to my inbox and another and another and another.  There's a lot of humorous websites you can pull from builtwith.com  about this. And yeah, they all land in my inbox. So, at this point, I'm like,  okay, this is obviously a problem, but what the hell is Mail Channels?  I've been using this thing for like at least a few hours now.  I still don't know like the who. I know the how, I guess, but not  the who. So it turns out, surprise, surprise, Mail Channels is an  email transaction service. And just to be on  the same page, transactional email is like your automated email. So like these are emails going from  robot to human. So like your password resets, your notifications, your  emails, newsletters, that kind of stuff. But what was really weird  and just like really confusing at the time is that also  they're sort of like almost like a cyber security company. Well, at least like they're trying to market that  yeah, we're an email transaction service, but we also stop, you know, the bad hackers with the  spam and stuff, which is very ironic because, you know,  the Boston.gov email tends to prove otherwise. But  you know, you find out too that when you start digging into the Mail  Channels website, it's its own little microcosm, you know, like it's like a multi  universe of things that you never really thought could be possible. Like you got people putting like  RDP credentials in the comment sections of blog posts, you know.  Like it's its own little universe of things that you never knew could be  possible. And it turns out Mail Channels, I was the ignorant one  because it turns out Mail Channels is the biggest player in the email transactional space.  It's got 42% of the market share and it's got double, more than double  the amount of domains or clients rather than like SendGrid, Mailgun  and all the ones that I knew that I've heard of before. But Mail Channels  turns out to be double, more than double the bit like SendGrid, for example.  So at this point, like I'm like, okay, how is this possible?  So some of the basics and just so we're on the same page, like SPF. So  Sender Policy Framework, this, what you gotta know is that in every email there's  like two from fields. There's one in the SMTP, at the SMTP level and the one that the user  sees in the actual email. So SPF, aka Sender Policy Framework  allows you to set a security control on the from field in SMTP.  So the one that the user doesn't see. And it basically just allows you to say, hey,  these are the IPs and host names that are allowed to send email on behalf of  my domain. So this is what it looks like in practice. It might  be a little small, but that's the SPF record of like Boston.gov  and there's a bunch of IPs that basically are saying, hey, these IPs are allowed  to send emails on behalf of my domain. But there's also a include statement  that includes relay.mailchannels.net, which I'm like, okay, that kind of makes sense  because like, you know, they use Mail Channels, right? And then I try  another SPF of another domain that builtwith.com said uses it. Same  deal. Always had that include statement with relay.mailchannels.net. Try a few others.  Same thing. And lo and behold, turns out that's part of the setup process of using  this Mail Channel service. That they tell people to put this include statement in their SPF  in order to use their service. But the thing is, if you start thinking  about it, right, that also means that all of their customers  can spoof each other. Because if, like, they all  have the same SPF, that means all of the other domains that have the same SPF  are authorized to send on behalf of each other. And couple that with this  Cloudflare worker thing, all of a sudden, it's almost like an open relay situation  where anybody can just go to the Cloudflare worker URL and just put in the  email details that they want to see, and bam, you can just spoof their emails.  And I'm like, okay, there's no way. This is a little bit too simple. How has this not  been found out before? And it turns out people back in 2016 were already  doing the same calculations like I was doing. I'm like, hey, so if  website A is using mail channels and website B has the same  SPF record, can't they spoof each other?  And again, mail channels in the comments section, they're like, yeah, so  the great thing about using us is you just call us and we'll stop the spammer.  And again, like, I don't want  to misrepresent. I mean, this was 2016, so they might have  some other stuff. But this is a fine situation  in my head going off here. So I'm like, okay, these guys obviously know  about this because people were complaining about it since 2016. But I'm just going to email  them. They had no official vulnerability reporting channel. I'm just going to email them and say, hey, I found some stuff,  whatever. And I email them, and within two minutes, the CEO  replies to me. Like, this guy had this email on speed dial.  It was crazy. I thought they were using like chat GPT for a second.  And he was like, yeah, so you're probably talking about the SPF  issue, right? Yeah, no, we know about that. We don't consider that a vulnerability  or an issue whatsoever. And I email them about, okay, but  you got the Cloudflare worker thing now. Don't you think that requires  like a little bit of a different kind of thinking, like at least mitigate that? And they're like, no.  And radio silence after that. There was no response.  And at that point, I'm also questioning myself because it's like, wow, okay, this guy seemed  very assertive. Am I the idiot here? Like, is it just  how these services work? But it turns out, no.  Like, other people, other companies like SendGrid and Mailgun  have a bunch of stuff that solves this situation completely, and especially  regarding to the SPF headers. So there's sender identity verification, which is basically  like what you do with Let's Encrypt certificates to prove domain ownership.  You have dedicated sending IPs, which allows you to actually put unique SPF records  in your DNS text record.  And then actual authentication on their API, which ties back the verified domains  when you actually try to send an email through the service, right?  And this is what, like, if you try to do the same thing with SendGrid, for example,  you basically, like, you put in the API key. You have to first verify  you own a domain. But if you try to send an email from a domain that you  haven't verified you own, it just says, get out of here, bucko.  Like, this is not how this works. Like, stop doing this. You're not allowed to do it.  So at this point, I'm like, okay, I need a bigger picture in order to understand stuff.  And I heard, like, through just random research that there's this thing called Project  Sonar from Rapid7, and they aggregate internet-wide data  regarding, like, HTTP, DNS, and stuff. So I hit them up in order to get access to this  database in order to, like, check  all these assumptions of, like, hey, are 2 million domains actually using this?  Like, what's another very important information if we want to  go forward with this? And so I hit them up, and they gave me access. And not only did they give me access,  they're like, hey, yeah, we're going to help you with this, because this is really weird. So shout out  to these people over at Rapid7. There were a few that I think don't work there anymore,  but they used to work at a time. So shout out to them.  And once we start digging through the data, it turns out builtwith.com is accurate.  And there are around 2,200,000 domains as of January 2023  that use mail channels. And at this point, Rapid7 reaches out to  them as well as part of the standard vulnerability disclosure process. And they're like,  hey, like, you know, we're working with Marcello now. And the CEO, again, replies in two minutes  saying, so we don't consider this SPF thing an issue,  but this is the piece of the puzzle that we are missing here.  Most of our clients are web hosting providers that don't  necessarily own the domains that they send emails from.  Okay? So it's a feature.  So what we have to understand is that apparently there's a niche market  out there for web hosting providers to send emails on behalf  of their clients, and mail channels is sort of like a middleman in order to  do that. So it's a feature, not a bug.  And it turns out, you're probably asking yourself, well, how do they stop this from being like Wild West?  Well, mail channels has a bunch of compensating controls, at least  according to them, that they do like signature checking, math, statistics, trends,  IP domain reputation. They also analyze the email responses  from people that receive the email. So if that means, I don't know if that means  if I just tell someone to fuck off, do they block them? I don't know.  I'm not sure how that works. But they also do OCR stuff.  But okay, fine. I couldn't really tell you how good these  compensating controls are because in none of our testing, none of the emails were blocked.  We probably sent like 100 emails between  me and Rapid7 and none of them were blocked. That being said,  our emails were clearly labeled as test, right?  So I don't want to misrepresent things. However, I did try to send myself like legit  phishing emails and they weren't blocked. So I don't know. But then he says  something very interesting. He says, domain owners are welcome to secure their domain  against impersonation by signing messages with DKIM and setting up an appropriate DMARC policy.  So mail channels is basically saying, yeah,  I mean, we have this SPF issue, but you just set up a DMARC record in DKIM and you're fine.  Nobody can impersonate you. But here's the thing. Remember that Boston.gov email?  SPF passed, but also DMARC was passing as well.  So what the hell is that all about? So DMARC really quickly is a way  of putting a security control on the from field that the user does see. So when we're talking  about DMARC alignment, we're talking about, hey, does the from field that the user does see  match the from field in SMTP and does it match  also any domain sent with any DKIM signature?  So that's when we talk about DMARC alignment. And in order to  test if DMARC does actually stop impersonation from this,  we had to grab a bunch of mail channels  customers' domains that had DMARC set up and DKIM  set up in order to test that. So it turns out out of the  2 million domains using mail channels, only 407 actually have any  DMARC record whatsoever. And out of that, only 105  actually use DKIM. So this whole encouraging customers to do the right thing is definitely  like it needs a little bit more encouragement, if you ask me.  So test case number four. So this is like the obvious next step. It's like, okay,  let's try to spoof an email from a domain that does use mail channels in their SPF  but also has DMARC and DKIM set up. Gits.com, I don't know what  the hell this is, but they are serious about email. They are using  email channels, but they have DMARC set to strict mode in regards to  DKIM alignment and their SPF record. So what this means is basically  if the from field doesn't match, right, the one that the user sees  in the email, that doesn't match the one in SMTP and doesn't match the one in DKIM signature, it just  rejects it. Like the end person doesn't even get the email at all. So this is like  very serious about email stuff. So, you know, Gits.com and it  goes straight to inbox. So at this point  we're like, okay, I don't know what's going on here. And it turns out  that DMARC and DKIM don't really actually fix this because DMARC passes  if SPF or DKIM passes. The or is the important part there.  As long as you pass SPF, you're also guaranteed to pass DMARC.  Like that's the gist here. And there's no actual proper way  to tell receivers to strictly enforce DKIM.  Apparently. At least from what we understand. So in summary, you're also guaranteed  to pass DMARC by using the Cloudflare worker that  uses mail channels. And we verified this really quickly as well through MailTester  because if you just send the email through MailTester, which is a service that  actually tests the delivery, like the chances of delivery of your email,  right, you can see, hey, DMARC passed, SPF passed, and we get a 9 out of 10.  So like, this is, you know, we're good to go here. There's no problems here.  We get docked a point for missing DKIM signature, but like  it'll still hit the inbox. And at this point, you're probably  wondering, but wait, like  what could there possibly else be? And yeah, I'm here to tell you, yeah, there's more. Hold on.  So we, while analyzing the emails,  we found a bunch of ARC stuff.  And we weren't really sure what this was. We've never seen these headers before in an email.  We, there was like ARC seal, ARC message signature, ARC authentication  results, and we were like wondering, what is this? Like I've never seen  this before. So let me introduce you to authenticated receive chain.  Okay, so that's what ARC stands for. And I quote here,  ARC allows an intermediate mail server to sign the message's original authentication results  so that even when SPF or DKIM fails at the receiver end, the receiver  can still check the chain of authentication records to determine whether the message can be  accepted. Okay, so what the important thing to know about ARC is that  it guarantees chain of custody. It doesn't necessarily  mean that the email wasn't spoofed, okay.  And ARC was made specifically  for email forwarding scenarios because  like if you want to send a newsletter out, what happens is that  the newsletter service sometimes modifies the body of the message and stuff  with like unsubscribe links and subject links and that kind of stuff. And so  that makes it impossible to use DKIM, for example, in order to actually  forward that mail securely. And ARC, it's a relatively  experimental protocol. Like it was written up I think in 2016. It was published  in 2019. However, that hasn't stopped a few brave  souls in adopting it. And by a few brave souls, I mean like Gmail, Outlook,  Zoho, Fastmail, like all the big ones. And ProtonMail, new, which  I found out, which you'll see in a second. It's pretty hilarious.  So this is what ARC looked like in practice. So when you want to  forward an email, right, ARC basically records  the authentication results, hence the ARC authentication results header.  Each hop the email goes through. So like you  send it from your email server. It gets sent through multiple other email  servers. Each hop puts the AAR header,  the AMS header, and the AS header each step of the way in the email  in order to record those results. And for the sake of this  talk, we're only going to talk about the AAR header  because that's where the juice comes in.  And again, like ARC is meant to determine  that the chain of custody hasn't been broken in the email. So like the message hasn't been tampered with.  It's not really meant to, it's left up to the end receiver  to determine if the email was spoofed  with the AAR header. So the end receiver  has to look at the AAR header, look at the SPF, DKIM, and DMARC results  in that header to determine if the email was spoofed or not.  So according to the RFC, this is what an AAR  header is supposed to look like. So you got your  hop, which is the I property there, and then you got the results of SPF,  DKIM, and DMARC. So you can see in the RFC example,  they all passed, and the end receiver has to take these results  and interpret that and put that in the calculations of the  spam score in order to determine if the email should go to inbox or should go to spam.  This is what MailChannel's AAR header looks like.  So basically, they're not checking  SPF, DMARC, or DKIM at all. And what happens is  they put in these properties that aren't really necessarily  representing what the header is supposed to do.  They put this auth equals pass. What auth? There's no auth.  You just do this. You just put the workers public. You don't need auth to do this.  So they don't actually check the SPF,  DMARC, or DKIM results. And at this point, we're just like,  please, why can't you just be normal?  This is the weirdest freaking thing we've ever seen.  It always claims auth equals pass in the AAR header.  We were really confused about that.  Unfortunately, though, because it's left up to the end receiver to  take this information and calculate the spam score with it, it's really impossible to know  how putting bad values in this header  will influence email delivery.  With Fortinet, for example, Fortinet is a good example  of anything, to be clear. However, they have  documentation out there that states, hey, you can check this checkbox in our product  and we'll basically override all of the SPF, DMARC, and  DKIM results with the results of the AAR header.  It's great. It's fantastic.  And again, there's no way to actually know how this gets interpreted  at the end of the receiver, unfortunately.  But what we've found through research is that  the presence, the sheer presence of ARC passing  in the email headers guarantees a better spam score.  And we confirmed this with ProtonMail because ProtonMail actually gives you the spam score  result, like it breaks down how it calculated the spam score. With Gmail and  Outlook, there really isn't a good way of knowing that. However, in our  tests, it seems like it sort of behaves the same way. So ARC passing  generally guarantees a better spam score. So if you're conducting phishing engagements,  all you have to do is adopt ARC and you'll have  a better chance of landing that email in people's inbox. A little Red Team Pro tip  right there. But as a consequence of this,  which is very interesting, is that if a domain  doesn't have any SPF, DMARC, or DKIM record at all,  using mail channels, you can actually  potentially spoof them at a higher success rate.  And then this sort of increases the blast radius a bit, where you can  basically spoof emails from domains that aren't set up to send  email, and you have a very high chance of actually landing that email in the inbox.  So this opens up the blast radius from like 2 million domains  to like over 3 billion, which is very interesting.  And again, the caveat being, as long as the end service  adopted ARC here, you have a higher chance of doing this, which is  very interesting.  In order to prove this, I was like, okay, well, first off,  I have to find a domain without any SPF  and DMARC record, which is pretty easy, but  there was one in particular that was super interesting to me, and about that time  my Black Hat talk about this got accepted. So that was really  weird also because I didn't actually submit the Black Hat talk.  Yeah.  So it turns out that I spoofed BlackHat.com.  So BlackHat.com...  So BlackHat.com didn't have an SPF or DMARC  record until February 2023, and  because ProtonMail, which is the service I use for my mail,  takes ARC into consideration, through the Cloudflare worker that  uses mail channels, I was able to spoof BlackHat.com because of  their adoption of ARC, ProtonMail calculated that into the spam score  and it just landed straight into the inbox. And these are the headers to prove it  where you can see ProtonMail is like, okay, BlackHat.com doesn't have a DMARC,  SPF, or DKIM record, right? So that  adds zero to the spam score. It's neutral. But hey, ARC passed.  So, hey, that minus one. And apparently  that's all that was needed to get that email into the inbox.  That little minus one. And again,  there's no way of knowing this  for sure outside of ProtonMail because Gmail and Outlook from  what we've seen doesn't actually give you the spam score calculations  like this. But yeah, this is very interesting.  So, another disclaimer before I do the demo here.  Don't do crimes, again.  But basically now this is public where you can go to  spamchannel.hacks.worker.dev  and you can basically spoof all of mail channels  domains and any domain that  potentially doesn't have a DMARC, SPF record. And this was based off  of Isangan's CloudFlare worker code, which is the original person who wrote this.  So shout out to him or her. But yeah, and it only tests on domains you control.  The code for this will be available after the talk as well.  So, quick demo here.  Just thinking  about it.  Uh-oh.  Hmm.  All right, I'm going to try that again.  Wow.  Wow, demo gods really hate me. How about this one?  Well, there are videos here.  Oh.  I don't know if we're going to be able to fix that in time.  But maybe we will. I don't know. Well, let's see.  I'm going to continue the presentation. Am I allowed to connect to the Internet?  Well,  at this point I think I'm not going to get invited to Black Hat, so I think at this point I'm just going to...  I mean, I don't know.  All right, well.  I don't know what's going on, but I'm going to continue and maybe somebody can come up  here and figure that out. Okay. Let's see.  Where is the presentation button? There it is. Okay.  Perfect. Well, hopefully I'll be able to show you a video of this. If not, you can literally just try  it yourself. You just go to that URL. So, disclosure  timeline. This all started in November of 2022. I initially contacted  mail channels and told them, hey, you know, this is a thing.  You should probably reconsider considering the Cloudflare workers.  You did this partnership with Cloudflare now and you got the Cloudflare worker thing going on.  No further response after that. January 2023, they were contacted by  Rapid7 and they were, again, response immediately  saying we don't consider this an issue, but then  no further response. Then in June of 2023,  I sent the final update to them saying, hey, you know, I got accepted at  DEF CON and I summarized all the findings and everything. Again, no response.  And then July of 2023, my mail channel sends me a random  email saying, hey, we noticed that you're speaking at DEF CON. Can you please share your findings  with us? To which I said, well,  I mean, I've been literally talking to your CEO since November of 2022, but okay.  And then so it turns out my vulnerability  reporting was going straight to spam.  Which is very ironic. I should have used mail channels for that  apparently.  So yeah, like a Gmail filter on that was literally sending my emails to spam for some reason.  But after that, they basically said, hey,  we introduced this thing called domain lockdown mode. So the takeaway here  is as of June 2023, if you're a mail channels customer, you have  this domain lockdown record that they implemented, which basically allows you to  specify the worker, the Cloudflare worker that  is actually allowed to send emails on behalf of your domain, or you can  completely disallow mail channels from sending emails from your domain at all.  So that's nice. Now the kicker here, though, is that  you can still send emails without  the domain lockdown record. So it's not like you  don't need a domain lockdown record in order for people to randomly just send emails  from your domain. So you need to actively go in there and put the record in. Otherwise, people  can just spoof your domain. It's to be announced when  this will be like a default thing where you're not going to be allowed to send emails  through Cloudflare through mail channels unless you put in the domain lockdown  record. So as of now, you can still spoof all  of their customer domains with this.  And so if you're an org that uses mail channels,  you should, well, if you don't know, you should check your SPF record, number one.  And if you do use mail channels, put in the domain lockdown record. You should probably go  through all of your also domains and just make sure that you have an SPF record  there set.  And if it's a thing, you can also have like, you can potentially  display a banner if an email that doesn't have a DKIM signature  comes from a domain that has implemented DKIM. I've never seen that. I don't even know that's a thing.  But that's potentially something you can do. If you're an email service  provider like Gmail Outlook,  don't just bump the spam score of an email just because ARC is passing.  I don't know why that's a thing, but  you should probably not do that because I don't think that's how  the protocol is intended to work.  And if you're an email transaction service, just don't do this. Just use  sender identity verification and dedicated sending IPs  because that just solves this entire swath of problems  and everybody uses this except mail channels apparently.  And so the final takeaway is email security is very brittle. It relies on, still relies on  users and orgs to do the right things. And ARC potentially could  incentivize a trend of gaming the system, which is something to consider as well.  And then finally, I want to shout out two researchers,  Shengkai and Gang, who basically is who I stole  the awesome graphics for DMARC and SPF explanations and stuff, and they did a lot of  the initial research into ARC as well. As well as Yisangan, who  made the initial worker code that I based the tool that I released off of.  And a huge shout out to the Rapid7 folks as well,  to help me do this research. Thank you.  applause  applause  Perfect. I just want to double check that.


url: https://www.youtube.com/watch?v=_2lH90C2nOM
title: DEF CON 31 - StackMoonwalk - Alessandro Magnosi, Arash Parsa, Athanasios Tserpelis
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=_2lH90C2nOM",
    "title": "DEF CON 31 - StackMoonwalk  - Alessandro Magnosi, Arash  Parsa, Athanasios Tserpelis",
    "description": "The rapid advancement of cyber defense products has led to an increase in sophisticated memory evasion techniques employed by Red Teaming and Malware Development communities. These techniques aim to bypass the detection of malicious code by concealing its presence in a target process's memory. Among these methods, \"Thread Stack Spoofing\" is a technique that hides malicious calls in the stack by replacing arbitrary stack frames with fake ones.\n\nIn this talk, we present two novel approaches, \"Full Moon\" and \"Half Moon,\" for tampering with call stacks in a manner that is both opaque and difficult to detect. These techniques manipulate the call stack to produce unwinding or logically valid stacks, thwarting conventional detection methods.\n\nWe also introduce a detection algorithm, Eclipse, designed to identify instances of these tampering techniques. This algorithm extends the functionality of RtlVirtualUnwind to perform strict checks on specific instructions and call sequences, enabling the detection of tampered call stacks. We evaluate the efficacy of Eclipse against both Full Moon and Half Moon techniques and discuss its performance and limitations.\n\nAdditionally, we explore the possibility of combining these techniques to create an even more robust method for call stack tampering that is resistant to detection. Our study contributes to the growing body of knowledge in the field of call stack tampering and detection and provides valuable insights for researchers and security professionals aiming to mitigate such threats.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2381,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   Thanks for sticking with us today. It's Sunday, it's a bit more chill. Some of us are already  flying home. Some of us are recovering from hangover. And the last of us are here. Thanks for  sticking with us. There's also some zombies there. Okay. So today we are presenting the  results of our research. Which is and we present a new approach for stack spoofing  targeting Windows on like specifically 64 bit architecture of Windows. Who we are? We are  three friends. I'm Alessandro Magnosi. I'm a principal security consultant in BSI where I do  mostly red teaming, offensive tool development and white box assessments. So source code  review, fuzzing and stuff like that. In my free time I work for I maintain some tools, some  offensive tools in industry which is an initiative by Marcello Salvari to support open  source developers. And in the rest of my time I'm a bug hunter for CNET red team. And there's  my colleague. Hey, my name is Arash. I work at CyberArk. I have kind of a dual job. I'm  very fortunate. I get to do a lot of threat hunting, detection engineering and I also get to do  red teaming when time allows for it. And our friend Thanos unfortunately couldn't be here  today. He also contributed to this work. He's a red teamer at Netitude. He was also great and  he contributed a lot here. So we we want to make sure he's mentioned. So here we are. Um so a  bit of story about this. All of this started back in 2022 when uh Namazo, a security  researcher and developer uh released a pop on Twitter like an image uh where it was showing  like a technique which then we uh popularized and um fix also a bit. Um and um this  actually like we were very interested in this research, in his research, in his work. So we  reached down to it. We started developing this in house. Um of course we didn't know a lot  about about what was involved with the technique. So we started this uh research and  development uh project. Uh we developed our own like version of the um of the technique  shown by Namazo. And after that we um continue researching on this technique. We will uh  also present, indeed we will also present a like the detection part for this uh technique  and other additional uh research avenues that we researched. So just to give you a bit of  background, let's define what stack spoofing is. What we what we mean with stack spoofing.  So of course you know that when you start a process on Windows, when you execute a binary,  you create a process in Windows which is a container and then one or more threads are tasked  with executing the real code of uh of the program. Every thread maintains a cold stack which  is an area of memory organized as a stack that maintains the information about all active  subroutines in a given time for a given thread. And what we do with spoofing is that we want  to um we want to create to substitute the frames with fake ones and this is usually never  done for non-malicious activity. This is always done for uh malware to hide the uh the  execution flow or similar stuff. So you will see here four different frames and why I put  this here is just to let you know what like to let you see what a cold stack is and you will  see that there are certain things that are like uh that appears that are common to uh to a  cold stack. For example we define this first two threads for this talk we will just talk about  this two frames as thread initialization frames which are usually at the bottom of the stack  of the cold stack. Uh like at the top actually of the cold stack. Then you have internal  frames of a specific programs that we will refer to this during the talk as a main modules  frames. And then you have the um the frames related to uh uh a cold stack. And then you have  a cold API uh an API cold. So why this is um how this is calculated by Windows. Um so the  stack is uh evaluated by Windows using an unwinding algorithm. An unwinding algorithm. And  this is this uses the information contained in the P data section of a binary or related  DLL. And in this P data section you usually have uh an exception directory. We contain all  the information about the functions. Specifically uh information about the um like every  every entry uh runtime function entry in this table contains information about the begin address  of a function, the end address. And a pointer to a structure which is the wind of a wind  infrastructure that contains um information about the size of the prologue, the count of  codes and all the in all the operations that were performed in a prologue of a specific  function. Um now why this is important. I mean this is used by uh by Windows to manage  exceptions. Uh but what we are interested in is the usage that this is done to calculate the  cold stack at runtime. And to calculate that what happens is that Windows evaluate the  frame um a cold a cold frame size a cold frame size uh dynamically using collecting the  information collecting the codes so the operation in the prologue that actually affected  the uh that impacted the frame size. And the operation are usually uh push of course. If you  push a register you're subbing eight on the stack. And if you unlock if you allocate memory  you're subbing from the uh from RSP. So you allocate state on the stack. So these two main  operation are what modify the the frame size. And then there is the push Mac frame which is  really not interesting for for our talk but yeah it's another it's another it's another  operation that impact the frame size. And this is important this is needed in in Windows  because if you remember 32 bit architecture um you in the prologue you always have like a  push EBP and then you uh you save the the base pointer so you have the base pointer pointed  to the um to the to the top of the to the top of the frame. And then you have the uh the ESP  pointing to the to the to the bottom of the stack. And this is useful um and like the the  contrary but yeah this is used to this is used for uh this is very useful to uh evaluate the  code stack because you can just navigate back the chain of EBP that are pushed on the stack.  But in 64 bit this is not possible because RSP is used both as a base pointer and a stack  pointer so to evaluate the code stack we need to um recursively get the size of uh of a  stack frame and then recover the return address and then evaluate again the code stack  frame and then uh the return address and traverse it back like this. So why we are  interested in the code stack? We are interested in the code stack because when you execute  malware on Windows you can generate some anomalies that can help with detection. So we  have in memory execution can be detected eh because when you inject code in memory if you're  using especially a um to to to run a malware you uh do process injection for example or  code injection and you're using an executable section on the heap what happens is that that  section will not have uh module associated so it that that executable memory is not backed  by a file on disk. If there is no file there is no P data section. If there is no P data  section there is no exception directory. If there is no exception directory there are  none like there is no way there is no information that the unwinding algorithm unwinding  algorithm can use to um dynamically get the size of that specific code. So what you  happen what will happen is that oh too much sorry. Uh what will happen is that you will  have something like this. So you will have a frame at a certain point that is not  resolvable and this is associate associated with uh with an unbacked memory region. Uh the  other thing you can uh you can the other anomaly that you can detect from the code stack is  when you use uh directory in direct syscalls and we are referring to direct system calls  actually direct anti-function execution like get proc address, NTDLL, anti-function and  then execute the function pointer is calling directly the anti-function and this will  generate a call stack that misses the um uh that misses the um why? Sorry for that. Uh that  misses the um what we the the frames associated with high level API call. This stack frame is  also generated if you're using an indirect system call so if you're just locating the  syscall instruction in NTDLL and then you jump to it. So the frame the stack the stack is  pretty much the the same and it misses the high level API frames of course. But these are  the anomalies when you want to detect this well you can do a periodic scan so you have a  tool that stop the frames uh that stop the threads uh system wide. Get the context and  unlock the stack frame. You can have a conditional scan which is a periodic scan with another  filter to filter for specific kind of threads that are in specific wait states for example.  Or you can use hooking or kernel tracing which is instead uh done dynamically when a system  call is involved you can use something like DWTI or another uh kind of uh driver to get the uh  to get the user mode uh call stack and and for detections. So to like S-tack spoofing uh  previous research on the topic uh lead to the development of techniques to defend from  specific scan, periodic scan, like stack truncation, stack cloning and stack hiding or uh to  defend against specific um specific specific rule based detection on the call stack when  executing a specific API. So stack truncation was probably the first one used and it's an  evolution it's a variation of normal return address spoofing where the where we replace the  malicious frame with a with a trampoline uh usually in a DLL or an executable and then we  nullify the return uh the return address prior to the um to the trampoline. This way we have a  cut call stack like this which is surely better than having garbage in the call stack but it's  still uh it still has a defect which is this this stack is not unwindable. So we still can have  a detection for this reason. Uh then we have stack crafting. Stack crafting instead is a  technique that is usually asynchronous like we have a system uh there is a specific  function that get called um and there are specific processes using that function in a  legitimate way. So what we do is that we record that execution that call stack at that  point and when we need to call our target function we just craft the same kind of uh of  call stack. So that we can in this way we can bypass detection like sysmon, antin for  specific call stack trace or uh similar similar detection. Then we have stack cloning. This  as well has been developed to defend from conditional scanning and the idea is simple.  Usually our implants go to sleep for most of like usually sleep most of the time. So when I  want to sleep using uh a delay execution like rate delay execution using a sleep or using a  wait user request at wait state using uh wait for single object. Well what I need to do is  just ant for a thread that is already with that state that is sleeping with that state and  then clone is call stack. This will make the call stack perfect perfectly legitimate uh or  apparently legitimate so uh we will be defended by conditional scan that ant for sleeping  begins. Stack hiding is similar but it uses uh another another kind of uh approach. So the  approach is that I will transform my thread in a I have a malicious code executing in memory  uh I transform my thread in a fiber so I have a fiber thread now and then I create another  fiber with a legitimate call stack that I use just for sleeping. So when I need to sleep I  just switch to the fiber thread to the other fiber that I created for sleeping and then this  process gets repeated when I need to go back from sleep. And this is what you have like this  is the uh this is the fiber with the legitimate call stack and this is the code uh in in  memory. So they you can see that there are two different area two different memory area for  the stacks uh and just one is active at a time. So what is our token contribution? Today we  want to present two techniques uh full moon and half moon that are designed to uh  obfuscate the stack at run time uh to avoid detection kind of base detection uh mostly uh or  hooking detection. So stack moving has some properties like it hides the caller from  memory, it obfuscates the stack so it's difficult to understand which kind of uh call stack  was actually taken was actually generated when executing a specific ABI or system call and  then it has an auto restore an auto restore technique so usually we use ROP to restore the  stack. We will see this is not always possible but yeah. Uh most most of them uses like  most for most for the most part is used ROP to restore the stack. So full moon is the  first technique and it operates like that. We have a function that we want to spoof API or  whatever and what we do of course of course we are executing this from from our main  module that can be in memory or can be like in this case it seems like it it's a program but  it can be even injected in memory there is no there is no problem. Uh this is for main  module if you remember I'm I'm referring to all the frames generated by the main module so  it's the like I just backed all the uh all the internal frames for the main module and what  I do is I select three frames well actually four to be a bit more stealthy in our  intentions but the needed are three and um these are a set set set for FPRAG frame, a push  reg frame, other sync frame and then yeah we added a concealed frame just to be a bit more  stealthy. And what they do is just at a certain point in the set FPRAG frame what we are  doing is that we are restoring the base pointer again and so this happens through this kind  of call which is mob RBP RSP where we save our current RSP which contains the uh address on  the stack that can save the return address of this frame and then with the second frame the  push FPRAG frame the push reg frame we push RBP on the stack. Now what happens this  creates an opportunity for us to modify the address that was pushed in memory because that  RBP now is on the stack. If you modify it this will be evaluated by the unwinding  algorithm as the address that should be used to restore RSP. And this gives us an  opportunity to tamper with this so that if this RSP points back to our thread initialization  frame practically what happens is that the main module will completely disappear from the  call stack. Okay this doesn't solve the memory problem so if you have you know unbacked  memory section this will not resolve that okay. But from the call stack it's not visible  anymore. Because doing just this will of course corrupt the execute the return flow of the  program we use the same gadget which is a job gadget here a jump RBX to hijack the return  flow so that we can execute a restore function which is under our control and this restore  function will reset the main module to what it was and just remove the fake frames. So this  is the technique in a nutshell. And this is how the call stack is set up and as you can see  there are the thread initialization frames and then there is no executable there is just  kernel base and these frames are all generated by our algorithm. Now these frames have some  logical inconsistencies that can be used for detection and my colleague will. Sure so I'll talk  to you guys a little bit about the IOCs and why this doesn't necessarily create a perfect  stack but does create a good looking stack. So if we look at the slide we have currently you  can see the spoofed frame the kernel base dot DLL open state explicit and you actually see a  location that plus zero X three nine D that's an offset. So what's going to happen is that's  the return address we would return to in order to continue execution within the stack. Now  why is this relevant and why is this in IOC? Because technically if we well let's talk about  what a call stack is. Based on the name a call stack is of course a series of calls. So you  will see an API call making another API call making another API call and this is often so you  can debug and you can see at what API you may have crashed at what section you may have  issues etc. So it is supposed to show a series of calls to other functions. Now if we look at  that spoofed frame the kernel base dot DLL open state explicit we go to the return address but  the return address isn't going to have a call because the return address is going to be after  the call. That's where we continue execution or we return. So what we do is we actually go  before the return address and we try to look at that little move byte pointer that we see  there for the open state explicit function. We can see that that is not a call and not only  is that not a call to another function it is certainly not a call to create private object  security with multiple inheritance. So immediately this becomes suspicious. And this isn't  something a legitimate dev would ever do because it would just hinder their debugging process.  It would impact them negatively. So this is something we would only see an attacker wanting to  perform. Now while I say this is an IOC it's really kind of a difficult IOC. You know it's  hard to deploy at scale. It's not really something you can hunt in your EDRs and if you  observe this on every single function there would be very massive performance hits. So while  this is an IOC we're not necessarily sure there's a realistic detection method yet. Outside  of the possibility of a utility such as Intel pin tracer which does it a little lower level  than the operating system itself. So if we look here we can tell you what we're looking for.  These are the call opcodes. This is basically the assembly that we're looking for in our  eclipse detector to observe full moonwalk. So we're looking for specific types of calls. Um that  mod rex w basically determines if it's like a long call or a short call for example. And then  we can see a relative 32 call. The call R64 calls a register. And then of course the  system call, the NTDLL lowest level call that you will often see because NTDLL often makes  the sys call for you. But if we were to observe there we would see a sys call instruction. So  this is the algorithm for all you PhD people out there. Um basically the idea is we're looking  for very specific things in our algorithm. Not just for stack spoofing but the detector is  looking for an invalid stack period. And not just by unwinding because as we know we can  actually fool the unwinder as previously shown. So what do we look for? We're looking for  unbacked memory regions. That's the reflective injection detected. Unbacked memory means  some injection was performed. A private RX commit memory region was created. This isn't  backed to any files on disk. No DLLs, no EXCs. So we consider this malicious often. We  consider some injection of some sort. There can be false positives with this to be clear. Um  JITs, browsers, you know C sharp you'll you'll see these private commit memory regions  getting created and executing code. So while this does help it's not foolproof to be clear.  The next is we actually look for the desync gadget. Because what full moon walk actually  does is it desyncs the stack with basically a ROP gadget in order to be able to  effectively craft its own stack for restoration as well. So we can just look for that gadget  and often that can be an IOC as well. Additionally the call mismatch detected as  previously stated. Um message box A is going to make a very specific call to the next  function. If we look at message box A, we look at the previous instruction and it's not the  right call to the next function, that's an IOC. And the wrong address detected as well. If  the address is just not a call, if it's not strict, if it's not correct, you know it has to  be a call and it has to be a call in a in the correct order. I I actually think I uh mixed up  the mismatch and the wrong address but the idea is the same. In one we're basically looking  for a call that's not a call or we're basically looking is it actually calling the next  function because that's what a call stack is supposed to do. This function calls that  function, calls that function for investigation. So this is full moonwalk running. We have a  successfully spoofed message box A. We've been telling you we're spoofing this message  box A. Now we run our detector. On the left you can see our spore our four spoofed frames  frames 8, 9, 10 and 11. Our detector first catches create file internal as a spoofed call  because the previous address does not, the previous instruction is not a call. And here's  what's interesting. We also get PSS query snapshot. Now if you look at the addresses, as I  said before, this does unwind. If you look at the PC address for PSS query snapshot, it  matches the return address for the create file function. So an unwinder is going to think  this is legitimate. This is in fact what was called, this is in fact where it needs to  return. But our detector knows better. Our detector goes there and says not only is there  no call, there's absolutely no call to create file W. All we've done is fooled the Microsoft  unwinder into thinking this looks legitimate. So if you actually use Microsoft's built in  unwinding, this is what we did here, it looks legitimate. We only caught this because our  detector is looking for more. Now there are a few false positives as mentioned before. Um we  see this a lot with JITs specifically. We saw this in WinDBG. It seemed to be uh uh have a  lot of JITing going on. We can see right here one of the processes for WinDBG has just  these two entirely unbacked memory regions. Um for reasons unknown to us, it appears JITs  don't always fully unwind and that these memory regions just always exist. And so there  will be false positives with JIT processes as usual. So we did testing to see what the false  positive rate actually was. We wanted to determine is this feasible? Is this something we can  actually do without you know overloading a team? And we determined kind of you know it's  it's not too bad. So we'll see we we tested this on five different machines. Uh standard just  means it was a standard Windows user machine. This is not a developer. This is just a person  who logs on, watches video, does work on Word documents and that's it. Uh dev is actually a  developer. Somebody who installs Visual Studio, sets up Postman, installs WinDBG preview.  And again you know it makes sense. The developer is going to have a higher false positive  rate, they have more JITs, they're developing more tools that are going to have weird  unbacked memory regions. You know no programming isn't really perfect and there's really no  catch all for this. We can see on Win10 the false positive rate is actually a little lower  than Win11 Enterprise. Um but you know we do see that for the dev machines it actually  decreased a bit. As far as Windows Server goes we see a pretty high false positive rate.  That's likely associated with you know you're deploying your web servers on this, you're  deploying your dot net applications, you're you're deploying all sorts of stuff that's going  to sort of increase that rate of false positives. And and you know just to end this as far  as detecting all this goes it's like I said for a hunter behind an EDR this isn't really  telemetry we get. Um some EDR provide call stacks for very specific functions so as to not  be too intensive. And we can sort of hunt on that and look for unbacked memory regions. But  as far as it goes for full moonwalk we just don't really have an effective way to check  every single function call and ensure that this call is actually a valid call. So in a way  this unwind ability is pretty effective in today's age. So after after developing the  detection we actually talked about uh other kind of avenues that we could where we could  actually make use of um this uh kind of knowledge. And so as we've seen um except for the  execute like in memory execution there was another problem which was the correct stack  frames allocated when we execute an I level API instead of going with the indirect Cisco. So  we developed this additional technique which is an extension and it's half moonwalk. Half  moonwalk is because we're just doing half of the technique. We are just considering what  is half like what is what we are calling and not really the caller. And so what half moonwalk  does is that we can always go to like we can always match an I level API to a Cisco. Uh  so half moonwalk takes as input um an I level API name and it's relevant um Cisco  instruction. Uh and it will trace uh all like it will trace the execution flow from the I level  API until it finds the relevant uh anti function. And what we're doing is that doing this  tracing we also collect all the information all the exception information so all the  information in the P data section related to the prologue. And what we do is that we  recreate the frames of the I level APIs before executing an indirect Cisco. So how we do  that we just need to literally emulate the prologue of the API level API. And what happens  doing this is that we can recreate the same kind of uh call stack. Perfectly perfectly  legit this time. So we also respect the um the location of the return address which is  placed after the call. And the call is actually matching what is being called. But we never  call the I level API. So this is literally a sys whisper type of indirect system call just  with uh the spoofed frame for the I level API. So now we have a little problem that we will  solve afterward for the emulate system call which of course is a function that will do  this spoofing and it's visible as for now. So we will solve this later. But um so we are  concerned about the return flow though. If we have these frames they will return back to  where they are supposed to return. But we didn't actually execute the I level API we just  emulated the prologue. Would that be enough to actually ensure that the return flow is  correct? Well yes and no. Uh so there are 3 strategies we can use. Uh 1 is the return uh  place the return on a winding. So this is terribly worded. Uh what I mean is that we place  the return address of the epilogue. Uh which of course is just deallocating the prologue. It's  just like literally rolling back the prologue so that will work. But we will be detected by  eclipse again then because uh we need to move the return address not after the call but on the  epilogue itself. Uh the other and this is what it happens. Instead we have to call to uh anti  protected to memory in this case. Instead of placing the return here where it's supposed to  do because there are all these tests we just move it to the epilogue. And this works of  course but as I said we are we can be detected again by by eclipse with this because if we  analyze the instruction before this return address it won't be a call anymore. So we have a  second strategy which is the targeted setup that works even better but it doesn't scale. And  the targeted setup is just like I can analyze what are the post uh call checks. What I call  post call checks are literally all these checks all these if that are executed after the  call. Uh and to avoid them from you know branching. To avoid the branching I just say what I  need to patch. I just see what I need to patch and then I patch it before actually  executing the call. Now this is this is pretty much it works but you can't do it anytime and  honestly it doesn't scale at all because you would need to know what thing to patch every  time you execute an arbitrary function. This doesn't scale at all. So the last thing we can  do is I don't know what is happening I'm sorry. Another thing I can do is using our break  points. Um so what it happens is that I I place a break point on return and we actually say  sliding our break points because we don't know how many frames we need to emulate. So if  they are more than four of course I need a strategy to out update the other break points  otherwise I will I will miss some frame. Uh anyway what it happens is that I place a I place  another break point at the return address when the function returns back I just execute  an exception handler that just execute the epilogue emulate the epilogue and then force the  instruction pointers to return. And that this way this this this scales well but I need always  executable I I always need executable memory because I always need to make the um the  exception handler like somewhere. I need to store the exception handler somewhere so I  always need some executable memory around floating around. So um as I said before um the we  also had a sort of a problem with the emulate system call because we said well there is no  function if you remember before there is no like this thing is actually pushing this frame  and then jumping to the sys call instruction here so if someone is looking at this emulate  system call it can be problematic. So what we can create is an opaque architecture that  as this is a if but you can place a switch case for example um that just will when ex when  this is executed it will execute so now we are stepping through here okay to emulate system  call W this is a frameless function it will execute something on the stack it will corrupt  the stack doing this but it will grab the position of this frame function and it will just  swap itself swap the frame of the frame of function with the frame function this way it will  restore the stack the call stack that will appear legitimate and here we have what  legitimates this like sequence of call is that we have a jump here to the restore uh proc. Of  course this is opaque it's not that great but what we want what is really important about  this is that even if we have something with no frame information associated as long as the  stack size so the modification on the stack are equal to something that we are creating and  it's framed we can always replace it and fix the call stack. Why this is important? Because  there are ways we can do that using standard Windows DLLs. So we selected this in particular  because it's very um it was already abused in exploit development to bypass uh uh exploit  mitigation um uh it's part of the exploit mitigation developed by Windows and it's the call it's  the call to NDR server call to. So we can use this kind of architecture here to completely hide  our caller again. So how this may work so if we can enforce in our implant maybe a stage  zero. If we can enforce in our implant this constraint uh so we want the our implant at any  time the internal the sides of the frames of the internal frames of our implant they should  always match the sides of the NDR stub call to stack. As you can see here you have a lot of  space allocated on the spy on the stack for this function. If we can enforce this uh this  constraint uh we can start a thread pointing to our shell code in memory which is our implant.  We can force these first two frames in the thread itself then we can start our implant and when  the implant needs to spoof a function what we can do is call the call at moon execute at moon  whereby the first frame spoofed is the invoke function which is an arbitrary call to anything  and then execute at moon with the rest of the AI level API frame and eventually call the spoof  function. So what this creates is a completely legitimate call stack where we have the frame in  the thread frame the thread initialization frames then we have the first two call to NDR stub  call uh NDR server call two and NDR stub call two then we have the execution of our implant we  have the return address spoofed with NDR stub call to stack which completely hides our implant  frames and then we have our phone executed with invoke and all the AI level all the remaining  uh AI level API frames. And then we have the system call again executed. This will hide  completely the um the caller as well so we are just we're just going back and try to you know  complete what our phone was not doing. So hiding the caller. Now the only drawback of this is  that you always in order to restore the functionality of the program on return you always  need uh another breakpoint placed on invoke. So you can handle these two frames as much as as  you want as we've shown before. So target that set up uh or um or uh return on epilogue or um or  exception or exception enders. But this invoke function you always need an exception  ender to actually restore the return address of the NDR stub call to stack and return to our  implant. Just a word about chat. Um we are starting a lot uh inter chat with shadow stack  mitigation and indirect branching tracing, indirect branch tracing and so far we didn't find  a way around chat. Uh it's not surprising. So what happens with chat is that there is a  shadow stack of course it clone like it maintains a list of all the return address uh that are  placed just after a call and when on return it will check if this return address is matches the  user mode um like the user mode the uh writable normal call stack and if they don't match  there will be a CP fault uh that will crash the program that will exit the program. Um there  is another another thing that is concerning about inter chat is that uh with indirect  branch tracing there is no easy way to modify the instruction pointer as well. We can't just  use exception ender as as much as we do now. Uh but the good thing is that even in uh machine  supporting chat so far uh there will there are always uh processes that are not chat enabled  like browsers and stuff like that that we can still abuse for executing this technique.  So key takeaways you will you always have the public block available here uh this will be  enhanced with additional uh box after this talk so in the coming days. Um this block of  course is uh like both of the techniques are usually like uh have been developed and  designed to obfuscate the stack at run time so if you're planning to obfuscate the stack  when you're going on sleep probably I'd rather use the stack cloning or the stack hiding  reason is well as you see there are certain logical inconsistencies in the stack so if you  leave it there for a long period of time you're increasing the chance of being detected by  eclipse etcetera or the denuncer is just just go there and see it and do a bit more um  analysis manual analysis on on the thread call stack. Um of course another another another  point is that this technique uh can be used wherever you use return address proofing as  an arrangement you can use sleep encryption I released a book uh not not long ago about  how to you can integrate uh sleep encryption technique to to to this to this um to this  technique to this stack proofing technique uh but it does a layer of complexity which is  not uh always easy to manage so a word of caution if you are trying to integrate this in your  own implant. And yeah I think pretty much it's it's everything um thanks a lot for joining  us and if you have any questions. Thank you. If you want we are at the start one sorry. So uh if  there's time we're happy to take questions but I think he's also saying if you want to meet up  with us after the talk we'll be happy to talk to anyone who wants to ask any questions.  Excellent. Yeah. Thanks man. Thanks guys. Thanks a lot.


url: https://www.youtube.com/watch?v=cO1JSzAdPM8
title: DEF CON 31 - Snoop On To Them, As They Snoop On To Us - Alan Meekins
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=cO1JSzAdPM8",
    "title": "DEF CON 31 - Snoop On To Them, As They Snoop On To Us -  Alan Meekins",
    "description": "BLE devices are now all the rage. What makes a purpose built tracking device like the AirTag all that different from the majority of BLE devices that have a fixed address? With the rise of IoT we're alsoing seeing a rise in government and corporate BLE survallaince systems. We'll look at tools that normal people can use to find out if their favorite IoT gear is easily trackable. If headphones and GoPro's use fixed addresses, what about stun guns and bodycams? We'll take a look at IoT gear used by authorities and how it may be detectedable over long durations, just like an AirTag.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 1402,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   All right, thanks for having us.  So today's talk is snoop onto them as they snoop onto you.  I'm Alan Meekins, I go by NullAgent on most social media, Twitter, Mastodon, all that  good stuff.  You'll find me as 7bitbyte on GitHub, and my personal website is actually kind of blank,  so I'll try to fix that this week.  And I've got co-speaker Rekka Dam, who couldn't be here today, he's stuck in Tokyo without  a passport.  And we've got Savage, our apprentice here today.  So just quick background, big robotics nerd, embedded systems, been playing with Linux  since I built my first computer.  Really love digital communications, which this talk is going to touch on a lot today.  And I occasionally do, I guess, grown-up work, but these days I am recklessly unemployed  and founder of Data Party.  So we're basically a hacker collective looking at the intersection of kind of just media  and all the things that hackers love.  So today, the thing that got me started thinking about this was actually a lot of police interaction  that my co-founder and I had over the years.  He grew up going through high school, getting pulled over by the cops basically every day.  And growing up, we were hearing a lot about no-knock raids.  And coming from a hacker's perspective and seeing things like no-knock raids, you kind  of start wondering, WWLND, what would Lord Nikon do?  So Lord Nikon would probably take a closer look at the boys in blue and maybe what they  carry and how they operate.  To give you some idea of kind of what the landscape is like on the digital world of  a cop, they have on the left the things that they carry, typically tasers and body cams,  a smartphone, pistol, things in the middle that certain companies wish they might carry  maybe, flying drones with tasers on them.  And then on the right, we have all the things that are in their vehicle, Wi-Fi hotspots,  surveillance systems that can actually do license plate reading.  So they actually do ALPR coming soon on their dash cams.  And of course, they've got a laptop.  And they have these weird little boxes called Axon Signal.  So if you remember the movie Hackers, one of the big things that they talk a lot about  is reading the manuals.  So first step was just see what was out in the open.  And so if you start reading through the manuals for all of these types of equipment, you'll  see a whole bunch of terms like cradle point and net cloud mentioned.  You'll see things like Bluetooth pairing.  And you'll see brand names like Axon Signal.  And then occasionally, you'll find some really cool things like, hey, this is exactly what  an error state looks like.  And here's an exact network map of what a police car looks like inside.  And you know, you keep reading.  And before you know it, you find all sorts of URLs that look tasty and delicious and  could be interesting.  So if you ever talk to public defenders and those sorts of people, they hear about this  thing called evidence.com.  And a lot of them don't realize that that's actually built by the same folks who make  the body cams themselves and all the digital tech.  It all just funnels up to this cloud.  So they typically access it through, you know, their agency name or their city or state or  something dot evidence.com and consume content.  And then if you keep reading, you'll start seeing some interesting things that might  get a hacker's eyebrows open a little bit.  But at the end of the day, the thing that really caught my eye is that the boys in blue  are actually, oh, actually, just a couple things, Wi-Fi access points and fleets and  so on.  But the boys in blue are actually the boys in BLE.  So there's a term that keeps happening a lot called Axon Signal.  And I keep seeing the word BLE co-occurring with that in the documentation.  So just kind of a quick trip down memory lane from DEF CON is when we're talking about  hacking the planet on the terms of BLE, there's been a great talk by Freaky at DEF CON 29  where she explained a lot of basic BLE, you know, the basics of BLE, how BLE pairs, how  it interacts with the host and so on.  And it's a great starting point to understand what might be going on under the hood of some  of these products.  And if you keep reading further, you might see some things like hand off all your privacy,  which deals with how Apple has a BLE protocol called Apple Continuity.  And you might also see some things called you better secure your BLE devices, which  has a lot of parallels to what we're seeing today.  And then lastly, Mike Spicer did a talk called I Know What You Did Last Summer.  So just a quick refresher on BLE.  I'm not going to go crazy deep on BLE fundamentals, but a BLE device needs to allow the other  devices that it wants to pair with to know that it's around.  So they send out these broadcasts, these beacons, a lot like how Wi-Fi access points also beacon  out.  And typically you'll find these types of parameters inside of there, you know, at least a MAC  address.  And then basically everything else is kind of optional.  So manufacturer data, services, products, company, local name, RSSI, possibly like URLs  and additional what are called gap fields.  So additional fields just like this.  And of course, you know, you start thinking about like, you know, if you were to reverse  engineer or to fingerprint devices that you haven't seen before, say like a cop device,  there might be a whole spectrum of ways that you might approach that problem.  So for instance, sometimes gap fields come in different orders.  So even two devices from different manufacturers might have identical data, but they might  put those fields in different orders.  So that might be a thing that fingerprints, or you might go and try to see if you can  find things on wiggle.net.  Wiggle's a big network of war driving that a lot of people who are participating in the  worldwide war drive right now, they're currently constantly feeding Wi-Fi and BLE data into  wiggle.net.  And then also, I built an app called RF Party, which is basically like wiggle in your pocket  without a cloud so that you can be entirely off grid.  And or, you know, you could also go down the decompiled apps route.  So how can we figure out, you know, what these police devices are actually doing?  And just as a note, most of the apps needed to manage these police devices are actually  currently in the Google Play Store.  So you can go download those and decompile them right now.  So without doing all of that crazy stuff, you know, how do I do this without violating  any kind of permissions or, you know, laws or anything, go back to reading the manual.  So I keep seeing this thing called Axon signals.  So what is that and what does it do?  Well it turns out that the devices highlighted in blue here are actually all Bluetooth enabled.  So body cams and tasers are designed to basically interact with one another.  And when a taser is fired, certain models can actually send out a Bluetooth beacon that  will notify the body cams and the surveillance in cars to start recording or to rather start  retaining their recording.  Body cams also have basically shot spotter technology built into them after the third  generation or the second generation of those.  And they can also detect a gunfire and trigger a Bluetooth transmission.  And then third to all of this, the pistol holster itself, there's attachments that can  detect when a pistol's unholstered and again sends out a Bluetooth beacon that is designed  to trigger the body cam.  And the same thing happens on the car side as well.  So again the blue circles here are things that are Bluetooth enabled.  So the documentation indicates that the same Axon signal technology is built into dash  cams.  And how are those dash cams triggered?  They can be triggered of course by everything on the left here, but they can also be triggered  by this little tiny box at the bottom that detects when your police lights are falling  off of your van there.  And that will actually detect when you turn on your siren, when you turn on your flashing  lights, and send a signal to the recorder as well.  And then finally they have a laptop in the mix that also takes a Bluetooth dongle.  I actually never fully figured out exactly why that is because it doesn't seem to actually  trigger much on there.  And then finally, you know, things that I didn't even feel like digging into, but they  have cradle point Wi-Fi hotspots in there that have all kinds of interesting things  in the documentation that I don't even feel like touching today.  So yeah, so overall that's the general architecture of how Axon signal works.  And you know, we went through the list of devices it's deployed on.  And so yeah, so where is it used?  It's also used, Axon has basically their fingers in every part of police life from how do you  charge these devices at home or in the office, and also things like interrogation rooms,  all of the systems inside of there.  And again, that documentation was a little bit more locked down.  So I don't have as much to share directly on entry points under those systems.  So again, with all of this in hand, how do you do analysis on this without having to,  you know, interact too closely?  And it turns out, go back to reading the manual, and there's this thing called an OUI.  And there's an OUI for the company Axon, which was initially Taser International, called  0025DF.  And that is the first three octets of most MAC addresses in the Bluetooth spectrum.  So if you register an OUI, and you want other people to recognize your device over Bluetooth,  you're going to use these in places like potentially in the MAC address itself, or in the manufacturer  data.  You can also have a fingerprint in there.  So for my app, RF Party, I actually built a database of over 4,000 device identifiers  simply by looking at OUI databases, and additionally Wireshark and their database, and of course  looking at manufacturer data.  And just kind of from my own, analyzing my own devices, discovered that there's a lot  of kind of like, I'm not sure if things are always on spec as far as like how manufacturer  data gets formatted, but there's a lot of interesting ways to fingerprint your devices  just looking at those.  So looking at the Taser OUI, you find out that they have a particular block size.  So they basically allocated 16 million MAC addresses that will be prefixed by this OUI.  So since we're talking about broadcast protocols in Bluetooth, a lot of people are very accustomed  to when devices are paired.  And when devices are paired, the broadcast will stop.  But there's a growing number of protocols being released lately, which rely entirely  on the broadcast capability, and basically none at all on the direct connection.  So some examples are COVID exposure tracking has a fairly cryptographically secure approach  to fingerprinting a person and then fingerprinting, or sorry, having a secure database of exposures  that's managed by your local authorities, and then you go and prove it and eventually  the other people who basically have been around you are essentially war driving.  When it comes to COVID exposure tracking, they're slurping up all these BLE broadcasts,  and they're saving the ones that have the correct fingerprint for this protocol.  And they're remembering all the public keys of the people around them.  So COVID exposure tracking is another great example.  It's one of the most pervasive Bluetooth broadcast protocols.  But now it's kind of winding down.  So if you look at Wiggle data, and if you do your own stumbling and whatnot, you'll  see that COVID is the COVID broadcast have reduced substantially over time.  But Apple continuity, on the other hand, is basically second as far as you know, from  my this is my personal ranking, as far as like total traffic that I see.  And Apple continuity has a lot of interesting things that it does.  Again, the app that we built called RF party, we parse all the sorts of things that hand  off all your privacy discovered.  So things like AirPlay IP addresses, yeah, your your iPhones are currently beaconing  your IP address.  In in BLE constantly, we get you can get information like whether or not the person's on the phone,  whether or not they're looking at a video if it's their primary iCloud device.  So these broadcast protocols have a pretty pervasive impact on your personal privacy,  and how trackable you are in public and public spaces and governmental spaces.  And then finally, we have a really new broadcast protocol that's coming online next month called  drone ID.  So drone ID will also operate primarily in Wi Fi.  But there's capabilities to do it in BLE as well and Bluetooth.  And I suspect part of the reason is that the BLE hardware might be more lightweight, more  ready to be embedded than some of the Wi Fi equipment to put on smaller drones.  And so again, on RF party, we're expecting to be able to parse that type of data.  And so finally, Axon signal.  So Axon signal kind of fits into this patchwork of prevailing and existing broadcast protocols.  So kind of taking our understanding of broadcast protocols and everything we found in the manual,  let's see what we can find.  So if you go to Wiggle right now, and type in 0025DF, you will find on the left, we have  the locations of police departments in the San Francisco region.  And on the right, we have the Wiggle map of where 0025DF returns have been heard.  And it corresponds pretty closely and of course, like, is clustered along highways that cops  probably patrol.  So there's a decade or more data in Wiggle.  If you run these queries, you're going to see that there's a worldwide footprint that  you guys in this audience have been collecting and putting on Wiggle.  So that's pretty dope.  So what can we do with this?  And what are the other ways that we can detect this?  So RF party could hypothetically, allegedly detect these sorts of things.  I can't demo that sort of thing.  Unfortunately, I haven't been contracted by any police departments to actually do any  pen testing on them.  So if you know any, let us know.  We'll be happy to help you figure out how to improve this.  But for demonstration purposes, it also turns out that GoPro video cameras have a broadcast  protocol that they implement.  So I took my GoPro and essentially assumed, hey, let's treat the GoPro like a body cam  and see what that might look like in RF party.  So here we have RF party in a public space.  I verified that my wireless connections are enabled on the GoPro.  And at this point forward, the GoPro will actually beacon so that my phone can manage it.  The other interesting thing to know about GoPros and their broadcast protocol is that  the protocol does not stop when the GoPro has been turned off.  The screen is off, but the packets continue to be emitted, and that MAC address, as I've  observed on my GoPro, never changes over the course of years.  So when I put in my GoPro into Wiggle, I didn't see anything lately, but that's probably changed  this weekend if I accidentally turned on my wireless connections.  And so if you had a continuous monitor running, and when you searched, if you searched for  the right parameters, so in RF party we're looking for the name of a GoPro, what we will  find is the first ping that we receive will show up on the map as a dot.  And if you click on that dot, you can see all of the packet information, all the service  information.  I blurred mine out because, of course, this is all my actual personal MAC addresses here.  And we're able to then see where we've crossed paths with that particular device.  And so here I am walking through a park.  These are my GPS pings in this ghostly white.  And then at the end, I'm going to run the query again.  And boom.  I've discovered that, hey, I initially saw the GoPro somewhere around here.  And then its final location was somewhere over here.  And there's a number of queries that we support, like duration and triggers that are coming  soon and alerts and that sort of thing.  So you could imagine that if this were, say, a body cam, so this is more of like a simulation  of if I were wearing a body cam.  And we actually have more data points along the way.  It just doesn't render it on the screen.  But you could imagine that you yourself could monitor for your own devices.  Or in the case of cop detectors, you know, or as far as in the terms of axon signal,  this essentially demonstrates an idea that there might be a way to detect cops.  And so if we switch back, cool.  What does this enable?  So specifically at axon signal, apps like RF Party and Wiggle enable us to potentially  do things like proof of body cam.  So what's proof of body cam?  If you read back on some of those no knocks that I mentioned and if you read the news  in the last couple years, you'll find out that sometimes police departments can be cagey  to release potentially damaging body cam footage, right?  And it's kind of hard to compel them because they kind of like to beat around the bush.  They're like, hey, we're not sure if anyone was there with a body cam.  We got to check our records.  They can really slow walk things.  So if you had a way to say, hey, I know this MAC address was in the vicinity.  I know this MAC address was at a particular event or a particular occurrence of a potential  police misconduct, you can more directly kind of light a fire under their butts and  more legally be able to specifically inquire about that information in court, right?  Other things that hackers probably think about, there was a competition I think at Black Hat  and Def Con many years ago, it was like over a decade ago, where people were competing  to make kill switches, computer kill switches.  So you hit a button and it thermites your hard drive or hit a button and the hard drive  catches on fire or various things, right?  So you can imagine if you're a very enterprising hacker, you might have a cop alert in the  Bluetooth spectrum that could trigger those sorts of things.  And of course, knowing things like RSSI and receive signal strength that's correlated  with these devices, you can very tightly detect the distance that a cop is to your computer  and the computer could self-destruct automagically, poof.  You could do things like identifying specific cops.  So a lot of cities, activists will file cases that will eventually put cops on something  called the Brady list, so basically a list of unknown police misconduct and bad behavior,  bad apples, if you will.  And you might want to get an alert if you're dealing with a bad apple, or you might want  to know, hey, I didn't catch that guy's badge number, but turns out I had Wiggle running.  And now you can go dig through that database, dig through your own logs, and now you know  their MAC address and you might be able to subpoena for the rest of the information.  And then the other interesting thing that organizations like ACLU and EFF currently  monitor are things like surveillance.  So where does AxonSignal factor into all of this?  If all of these body cams start doing facial recognition, for instance, so these body cams  actually have 4G LTE connections, and they actually can live stream video at any moment,  and that's, you know, I'm not even talking about the cloud this year.  But there's a huge question about what's the prevalence of this technology, especially  as we understand more and more about these features, especially like the license plate  reader being embedded directly into the dash cam.  What if that license plate reader technology gets embedded into body cams?  There's kind of a, not even a slippery slope, it is a Homer Simpson falling down a ski mountain  worth of interesting problems here that we might want to understand as civilians and  for our civil liberties how prevalent these technologies are.  So finally, tools like RFParty, we were absolutely inspired by these types of questions, and  we really want to enable other people to be able to experiment and learn about these devices.  And of course, you know, if cops are trackable, we're very trackable as well with things like  our GoPros, our Apple Continuity.  How do we verify that any of those devices are actually in airplane mode?  If you read the instructions for, you know, iPhone, it says, you know, turn off the Bluetooth  connection, turn off airplane mode.  There's not really a great way for an ordinary person to verify that.  And kind of what we're also pointing out here is that every device, not just AirTags, every  device is an AirTag, right?  So we actually need a way to detect all Bluetooth devices.  We don't need one-off solutions that only work on iPhones and then take three years  for Android to catch up and then leaves everyone who runs Linux completely in the lurch.  We actually need a solution for everyone, right, and for every possible device.  So that's kind of, that's the talk.  And here are some tools.  So the biggest tools used here were the PDF viewer.  The second most used tool was an OUI database.  And then finally, Wiggle.net.  And then some other super handy tool is NRF Connect.  NRF Connect kind of is the only multi-platform Bluetooth scanner right now that's allowed,  because they're actually allowed on the Apple Store.  Apple doesn't really allow hacker tools in their app store.  However, they do use the Nordic semiconductor Bluetooth chips.  So somehow, Nordic got an app in their store.  And then so, yeah, so we're building this thing called RFParty, runs on Android, and  then it's on Mac, Linux, and Windows, coming soon.  And then finally, we have some open hardware as well.  And then all of this is open source.  You can get it on the App Store and help us get home.  And party on, everybody.


url: https://www.youtube.com/watch?v=tKJzsaB1ZvI
title: DEF CON 31 - Smashing the State Machine the True Potential of Web Race Conditions - James Kettle
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=tKJzsaB1ZvI",
    "title": "DEF CON 31 -  Smashing the State Machine the True Potential of Web Race Conditions - James Kettle",
    "description": "For too long, web race-condition attacks have focused on a tiny handful of scenarios. Their true potential has been masked thanks to tricky workflows, missing tooling, and simple network jitter hiding all but the most trivial, obvious examples. In this session, I'll introduce multiple new classes of race condition that go far beyond the limit-overrun exploits you're probably already familiar with.\n\nInside every website lurks a state machine: a delicately balanced system of states and transitions that each user, session, and object can flow through. I'll show how to fire salvos of conflicting inputs at high-profile websites to make state machines collapse, enabling you to forge trusted data, misroute tokens, and mask backdoors.\n\nTo handle this explosion of attack surface, I'll share a polished methodology designed to help you eke out subtle tell-tale clues and scent blood long before sacrificing anything to the RNG gods. I've also taken lore amassed over years of research into HTTP Desync Attacks and developed a strategy that can squeeze 30 requests sent from Melbourne to Dublin into a sub-1ms execution window. Alongside the open source tool, we'll also release free online labs so you can try out your new skillset immediately.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2538,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   Thank you. Thanks for coming. I know it's an early start. Good morning and welcome to  Smashing the State Machine, the True Potential of Web Race Conditions.  Have you ever seen a vulnerability that made absolutely no sense? Something that didn't  just leave you wondering why would anyone code that, but asking how is it even possible  to write code that has that effect? Maybe you even got hold of the code and stared at  it for hours and it still made no sense. And perhaps if you showed it to somebody else,  they'd say something like, oh, it must be a race condition. In this session, I'm going  to share with you tools and techniques to discover and exploit that kind of race condition.  Let's start by surveying what we do understand. What race conditions have you seen or exploited  in the wild? Maybe things like reusing a single use voucher multiple times or bypassing some  kind of rate limit or reviewing a single product multiple times. One of my favorite ones that  I found is I noticed that you can reuse a valid single reCAPTCHA solution multiple times  within a short time window. And when I reported that to Google, they were like, oh, yeah,  that's not good, but, well, unfortunately our system is so distributed that we can't  patch this. So that technique still works on a bunch of websites today. But all of these  examples could be classed as limit overruns, right? They're all about doing something more  times than you're supposed to. But if you go digging through every post that you can  find on the topic, you'll land on one called race conditions on the web by Josip Frankovic.  And in this post, he describes four vulnerabilities and three of them are regular limit overruns  and one of them is different. The vulnerability that he found took two months just for him  and Facebook's security team to figure out how to replicate it. And the issue was that  sometimes when changing your email, Facebook would put two confirmation codes for two different  addresses using two different parameter names in a single email. Now, I had no idea what  was happening here and I don't think they did either, but one thing was clear. This  wasn't a limit overrun vulnerability. And so last September, six years after I first  read that blog post, I decided to try and figure out what happened. And gradually came  to realize that the race condition attacks that we all know and love already are just  toy vulnerabilities compared with what else is out there. So in this session, I'm going  to show you the true potential of this attack class, tools and techniques to achieve this  potential, and case studies and a live demo to show some of the insanity that's out there  waiting for you to discover it. After that, I'll share where things can be taken further,  how to prevent these attacks and the key takeaways leaving five minutes for questions. On certain  slides you'll see there's a mortar board icon and that just means I've designed a free online  replica of this vulnerability and published it in the web security academy. So you can  practice exploiting that vulnerability on a live system for yourself. Now, to communicate  the true potential of this attack class, I'm going to use a multi-step vulnerability that  I discovered by accident a while back. I noticed that when I logged into this website, it asked  me to select a role before proceeding to the application. So I thought, okay, if I visualize  the state machine for the user's role, it will look something like this. And well, maybe  we can just jump from the role selection page to the back end without choosing a role and  get some kind of privilege escalation going. And I tried that and it didn't work. And I  thought, well, I guess it's secure then. I mean, look at that diagram. It looks pretty  secure, right? But the diagram was actually wrong. It's missing a state because it's not  zoomed in enough because it's assuming that the get request to the role selection page  doesn't change the application state. And as it so happened, for reasons that I don't  entirely understand, the application was creating every session with administrative privileges  and then the get request was revoking those privileges. So by failing to zoom in, I almost  missed quite a serious vulnerability. But, you know, that's just my bad, right? Because  everyone knows that multi-step sequences are a wonderful source for all kinds of serious  vulnerabilities and so it's essential to always zoom in as much as possible and test every  possible permutation of a process like this. But researching race conditions, I found myself  looking back at this finding and thinking, well, is that the furthest that we can zoom  in or can we go further still? What if the application had dropped our privileges immediately  using a second database statement? There would still be maybe one millisecond time window  where every session had administrator privileges, but I would never have discovered it. And  that's a little bit of a scary thought because, well, any login form could have that vulnerability.  It doesn't need to be a multi-step login. And actually worse than that, it shows any  HTTP request might be transitioning the application through invisible vulnerable substates like  that one and these could potentially lead to some serious attacks. In other words, we  all know that multi-step sequences are really dangerous. And with race conditions, everything  is potentially multi-step. That is the true potential of web race conditions and now it's  time to start hacking some stuff. To discover a substate, you need to know  we need a collision. That means we need two requests, one to trigger the substate or the  race window and another that accesses the same resource at the same time. So in the  example we just saw, that might mean trying to log in and access the admin panel simultaneously.  However, there's a major barrier to making this happen which has plagued this attack  class ever since it was invented pretty much which is network jitter which randomly delays  our requests inconsistently meaning that the race windows don't line up and the  vulnerabilities don't get discovered. To solve this problem, I've developed the single packet  attack which lets you make 20 to 30 HTTP requests arrive at the server simultaneously  regardless of how bad the network jitter is on your connection. Under the hood, this technique  is all about TCP and HTTP. The previously best known technique was called last byte  synchronization and it takes advantage of the fact that web servers generally won't  start to process a request until the whole request has arrived. So with last byte sync,  you withhold the final byte of each request and that makes the final packet of each request  nice and small and it makes the jitter not quite so bad but it only goes so far. But a  couple years back, I read an academic white paper called timeless timing attacks and there  they noticed that with HTTP 2, you can actually stuff two entire requests into a single TCP  packet. And they used that for timing attacks which was pretty cool. But I was wondering,  well, can we adapt this and use it for base conditions? There's only one barrier here  really which is to find a base condition reliably thanks to factors like server side jitter,  we need more than two requests. So what I did was I took these two techniques and smushed  them together to create a single packet attack which completes 20 to 30 requests in a single  packet eliminating network jitter. And I've just released this in an update to the open  source tool turbo intruder. Now, this technique frankly is pretty obvious. And actually I was  like this is so obvious and I was like, well, I wonder if anyone else has already done it.  And I Googled and it turns out someone else implemented something quite similar for a  master's project back in 2020 but nobody noticed. So why is this, why am I so excited about  this technique? Well, it's because this isn't just some cool implementation trick. After  refining this technique over months of research, it now works on all major web servers. I can  still fit the entire algorithm on a single slide. And ultimately it brings insane  performance in a parcel that's so easy to implement, I think it will end up in all major  web testing tools. The reason it's so easy to implement is that thanks to some creative  abuse of Nagle's algorithm which is in all operating system network stacks, you don't  need to code a custom TCP or TLS stack. You can just take a HB2 library and bolt this  feature onto the site. If you're tempted to make your own version, I'd say go for it.  And I think Golang's HB2 stack is probably one of the easiest to extend in that manner.  And I'm really looking forward to seeing where other people take this technique in the  future because it can definitely be developed further. But of course the thing I'm most  excited about is the performance. So to benchmark this technique, I repeatedly sent a  batch of 20 requests from Melbourne to Dublin and I measured the gap in the execution  time stamp of the first and last requests to reach the server in each batch. In other  words, how close together the whole batch landed. And using last by sync, I saw a median  spread of 4 milliseconds and a standard deviation of 3 which is to be honest, not that  bad. It's better than I expected. I think that's because I had data centers at both ends  of this benchmark and if you were using Australian consumer broadband, you might have a  different experience. And then I retried it with a single packet attack and saw a median  spread of 1 millisecond and a standard deviation of 0.3. In other words, the majority of  these 20 requests traveling 17,000 kilometers were getting executed in the same  millisecond on the target server. In terms of what that means in practice, well, you  could say, okay, it makes this technique 4 to 10 times more effective than last by sync. Or  on one real vulnerability that I found, I was able to replicate the issue within 30  seconds using single packet attack and it took over two hours of automated attempts to  replicate the same issue using last by sync. In other words, if you want to kind of  summarize this up in a little sound bite, I would say by eliminating network jitter, the  single packet attack makes remote race conditions local. Now that we've solved network  jitter, it's time to go hunting for some bugs. Now limit overrun vulnerabilities are easy to  find. You look for a limit, you try and overrun it. But going beyond that, things get a bit  trickier. And after months of manual testing and discovering every possible pitfall, I've  developed the following three‑step methodology to find these bugs reasonably  efficiently. First you predict where you might have potential collisions. Then you probe  those places to identify clues that there's a substate there. And finally, you prove the  concept by figuring out what happened and using that knowledge to build an exploit.  Prediction is just about efficiency. In theory, because everything is multi‑step, every  single request is an arbitrary complex multi‑step process, we ought to test every possible  combination of end points on the entire website and any other websites that have the same  back end. But that's not very practical. So instead, we're going to home in on places  likely to have collisions that have serious consequences. After doing that, we can  furthermore rule out end points that don't have as much collision potential. So for  example, two threads that are editing a single piece of data at the same time, that could be  quite interesting. Whereas if the two threads are just depending to the same piece of  data, that's less likely to have an interesting outcome. Similarly, you can ask, are these  requests going to be editing the same record in the database? If the password reset  system is storing tokens in the users table, then if you do two resets for two different  users at the same time, then two different rows of this table are going to be edited and  you're not going to have a collision. Meanwhile, if it's a password reset system that  maybe SMSs you a pin and it stores the pin in your session, then you can use your single  session to do resets for two users and cause a collision and maybe something interesting  will happen. Once you've built your requests, it's time to just take them and probe for  clues. The essential thing here is that it's quite easy to fail to recognize a clue. So  the first step is to benchmark the normal standard behavior of the application by sending  your requests one at a time with a delay between each of them so you don't trigger any races.  And then you just resend them all at once using the single packet attack and look for  anomalies, clues, any deviation from the behavior that you saw during the baseline. If you  don't see any, it might mean that they're secure or it could just mean that you need to tune  your attack timing which I'll talk more about in a case study later on. Finally, by this  point we should have found an anomaly. So all you need to do, which is often the hardest  part, is actually understand what happened, clean it up and replicate the behavior and  explore the impact. Now, a word of warning here. Exploring the impact might sound kind of  obvious, but if you're doing this methodology right and being ambitious with it, you're  going to run into some quite weird and unfamiliar behavior and as a result the path to  maximum impact may be quite hard to find. So I would suggest thinking of the behavior you  found as a structural weakness and looking throughout the application to find security  relevant features that rely on that structure and also don't just stop and report the first  exploit that you find. I actually made that mistake myself and lost out on around $5,000 of  bug bounty as a result. So now we're going to take a look at a tiny slice of what you might  find if you apply this approach in the wild. Git lab lets you invite unregistered users to  administer projects via their e‑mail address and I thought, okay, sounds juicy, I'll test  it. So as a baseline, I just invited one address six times. This created one invitation,  one invitation e‑mail and caused six responses saying status success. When I resent these  requests in one packet, we saw one status success, five error messages and two e‑mails. So  we've got two clues that we've hit a race condition here. The first clue is obviously two  e‑mails from six requests is quite suspicious. And the other one is that the responses that  we got differed from when we did the baseline. Note that if we hadn't done the baseline and  we just looked at those responses, we probably wouldn't have spotted that second clue. So  using that race, I was able to create multiple invitations with the same e‑mail address,  which I at first thought, well, that's nice, but kind of useless. But I noticed that the  Git lab, the page on Git lab that lists pending invitations only displays one invitation per  e‑mail address because it doesn't think that multiple ones can exist. So you can make  a kind of a low privileged invitation. And if an admin sees it and deletes it, it actually  effectively says user ‑‑ it says user was successfully removed from project and replaces  it with a higher level invitation behind the scenes. Now, that impact isn't amazing because  you need quite high privileges to exploit it in the first place. But it got my attention  kind of focused on Git lab. And it left me wondering, well, maybe there's another  angle that I can take that's a bit more deliberate and will achieve a more serious impact.  Now, one approach to finding inspiration for these kinds of race conditions is to look  to classic multi‑step exploits and see if you can find a race condition adaption. So  for example, there's a classic exploit where you add an extra product to your basket somewhere  in the payment validation process after taking it to checkout. And if you time that right,  you can get the extra product for free. And I noticed that if you draw the state machine  for Git lab's e‑mail verification process, it looks kind of similar. So maybe if we change  our e‑mail address while Git lab is validating our previous e‑mail address, it will end  up validating the wrong one. And that would be high impact because it would let me hijack  administrator invitations intended for other users. So I tried probing for this and it  didn't get any clues or anomalies. But I noticed that the e‑mail change response was arriving  after the confirmation response every single time. Presumably because changing e‑mail  was a slower operation. So it was possible that there was a race condition present, but  I just wasn't lining the requests up correctly. And after some trial and error, I was able  to fix this by sending the confirmation request 90 milliseconds after the e‑mail change.  But that approach, although it did work on Git lab, it's not ideal because it rules out  the single packet attack. And I later discovered an alternative approach that I think is better.  Web servers often delay requests that are sent too quickly. And we can take advantage  of that by sending a single packet which contains first the slow processing request followed  by a load of dummy requests that trigger the right amount of delay server side and then  finally the fast processing one at the end. So using that technique, you can do a kind  of staggered attack and because the delay is implemented for you, server side network  jitter is not going to make that technique fail. Lining the race window up like this  on Git lab revealed a massive clue. Sometimes the e‑mail confirmation token was sent to  the wrong address. Unfortunately for me, although this looked really exciting, the misdirected  code was only ever valid for confirming the already confirmed address and therefore it  was useless. But it showed that there's at least one sub state hidden inside Git lab's  e‑mail change end point. And so it's worth digging further on that functionality. And  I'm going to do this via means of a live demo on a remote server hosted in Ireland over  the conference Wi‑Fi. Cool. So here we have Git lab. And here I'm just going to show, if I  change my e‑mail address, then the new one I entered, it's just been set as pending,  right? Because I have to click the confirmation link to prove that I own this e‑mail. So  that's what we're going to be targeting. So let's see how it goes. I did test this earlier.  It's not 100% reliable. Sorry. Okay. On this Wi‑Fi, it was ‑‑ I mean, it's never really 100%  reliable to be honest. Okay. So first I'm going to probe for clues. So I'm going to try and  change my e‑mail to six different e‑mail addresses in the same millisecond using the  single packet attack. And I'm going to get all of these e‑mails. They're all going to me,  but every e‑mail address is unique. So I'm going to send this. The responses should  arrive all at once. Yep. Good. And the first kind of tiny little hint that something  interesting might be happening is in this X runtime header. So we can see the server  processed this request in 350 milliseconds. And for something that we know is sending  an e‑mail, that's quite fast. It's almost like they're passing some data to a background  thread. And the background thread is sending the e‑mail. And as soon as you've got data  being passed between different threads, race conditions become a lot more likely. So that's  a nice little hint. But it's definitely not evidence that there's a vulnerability there.  For evidence, I'm going to check my inbox and we'll see what we have. Okay. So we've got  our eight confirmation e‑mails. And if I scroll through these with a bit of ‑‑ right.  There we go. Okay. So here this was sent to demo six at port swigger.net. It was sent to  demo four. But it's intended to confirm demo six. So this is our clue. This has been sent  to the wrong address. But it's not a vulnerability because this link isn't actually going to  work. It's just going to say the confirmation token is invalid because that confirmation  token has been overwritten by one of the ones that came after it. And for some other  reason. So we've completed the probe phase and now we're going to prove the vulnerability  by switching to an exploit. And this is where things get a little bit less reliable. So  I'm just sending two requests in a single packet. One is setting an e‑mail address  that goes to my inbox and one is setting spoofed at local host which is obviously not supposed  to go to my inbox. And this is one other thing to mention here. This little line here.  So in order for the misdirected confirmation token to ever be valid, you have to trigger  Git labs re‑send token functionality which you can do by changing your e‑mail address  to the same value twice in a row. And if you don't do that, the token is never valid and  it took me around two months to discover that. So I'm going to run this and if we're  really lucky, we'll get a misdirected token and if we're even luckier, the token will  actually work. Okay. So that looks kind of promising. This is intended to go to spoofed  at local host and it went to me. The killer question is, is the link going to work? It  does first time. I should have pretended it was always going to work first time. Cool.  So yeah, that was that. So I originally found that vulnerability on Git lab.com and I could  not resist obtaining the e‑mail address albinowaxed at Git lab.com and you can view  that e‑mail address on my profile if you go there. But that shiny finding left me wondering  about what a code looked like. And the vulnerable code starts out in a Ruby on Rails framework  called devise. And the problem is there's an inconsistency between how the system decides  where to send the e‑mail and what to put inside it. The e‑mail is sent to an address  stored in an instance variable which is passed directly to the thread that sends the message.  Meanwhile, the body of the e‑mail is populated using data from a server side template engine  fetched from the database. Which means that the data in the database can change in the  meantime leading to this discrepancy. And the impact is quite significant. So as I mentioned,  you can use this to hijack pending invitations intended for other people and just gain administrator  access to random projects. But also Git lab can be used as an open ID provider by third  party websites to create a sign‑in with Git lab button. And depending on how the third  party website does that integration, this can enable a load of follow‑up attacks against  that third party all the way up to arbitrary account hijacking if you're lucky. If you  were to find this bug in a major open ID provider, it would be a pretty big deal. Now, I reported  this to Git lab and they patched it pretty fast and then I reported it to devise and  things did not go so well. Over the span of 200 days I reported to over four addresses  and I received no reply from them until last week. And there's no patch available yet but  at least they've applied so maybe there will be a patch soon. So I went hunting for other  bug bounty sites using this library. And as it turns out, it's really popular. Loads of  Rails‑based sites use it. It's really easy to fingerprint because it registers an unauthenticated  end point slash users slash confirmation that you can just spot. And because of the way  the library is written, every website integrates with it slightly differently and as such every  exploitation journey is slightly different and it's great practice and good fun. So a  couple of highlights that I encountered during this process were some sites had visible  locking. They were obviously only processing one email change at a time. So they were secure.  On another site, the confirmation email that they generated didn't tell you which address  it was supposed to confirm. So there were no hints that the vulnerability was present  and it was really unreliable on that site. So I had to write a script that would do the  attack, receive the email, pause it, click the link and reload my profile to work out which  email address had actually been confirmed and then I had to run it for 14 hours to actually  compromise another email. On a couple of other targets, their visible email change  functionality is secure against this attack but device registers a different hidden end  point for triggering an email resend and that was still vulnerable. Now with that, let's  move on from GitLab and device. So race conditions are weird and I've saved the weirdest one  for last. This was another token misrouting flaw but the two requests that triggered it  could be sent with a 20 minute delay in between them. So you might be thinking, well, that  doesn't look like a race condition but it was really unreliable so chances are it was  and after some analysis, what I think was happening is that my email change requests  were getting put on a queue which was then being processed by a multi‑threaded batch  job once every 30 minutes or so. So the timing of my request was practically irrelevant and  the vulnerability was triggered basically by my request volume rather than the timing  and also the only reason I discovered it is because I noticed two emails were sent to  the same address. Which over the course of this research, due to things like this, I've  begun to regard spotting anomalies like that as the single most important skill for finding  race conditions, especially for deferred ones like this where the response the application  sends to your actual request is never going to tell you a vulnerability is present because  the vulnerability hasn't even been triggered yet. Now, I focused on email‑based attacks  during my research but where else can you find these things? Well, basically everywhere  but one pattern that you may well encounter is partial construction attacks. These occur  when an object is created in multiple steps creating an insecure middle state like you  can see in the code snippet here where this token variable is briefly not set. I didn't  use this as a case study because I actually wrote this code myself about ten years ago  but it was not supposed to be vulnerable. Now, this type of attack is most likely to  work on applications that support default or null type values and don't just throw exceptions  when they encounter them. So think SQL PHP. But that's not a strict requirement and for  a completely different type of partial construction attack, check out the linked vulnerability  found by Natalie Silvanovich in Google's web RTC implementation.  Another angle for further research is exploring the root cause of race conditions from the  ground up which is unsafe combinations of data structures and locking strategies. There's  three main strategies that you'll run into. The classic defense is locking. So, for example,  PHP's default session handler only processes one request at a time in a given session.  So that means two things. Firstly, they're not going to have a session‑based race condition  but also if you trigger, if you try to trigger a database layer race condition using a single  session, you'll fail to find it every time. So it's important to recognize this behavior  and work around it by doing things like using multiple sessions.  The probably the most common approach that you'll see in session handlers and ORMs is  batching. So this is where they read the entire session, let's say from the database into  a local in‑memory copy and then any reason writes that the application does during that  request are applied to that local copy and the whole copy is written back to the database  at the end of the request life cycle. So this makes the values internally consistent during  that request life cycle. But as we saw with device, as soon as data gets passed to a background  thread, you're kind of outside the scope of that protection and everything falls apart.  And also, if you have two requests operating on the same record simultaneously, then generally  one will end up overwriting the database changes from the other.  Finally, if there's no defense present, all the bets are off basically. And you see that  most commonly with databases where people aren't making adequate uses of transactions.  But you also see it occasionally with custom session handlers. And if you find a session  handler that has that property that's not doing batching or locking, that needs some  really heavy testing because there's a whole load of completely plausible, reasonable code  patterns that suddenly have critical vulnerabilities if they're built on top of a vulnerable session  handler. So it's ‑‑ I would say I think it's almost impossible to write secure code  at the application layer when you're building on top of a session handler that's not doing  some kind of synchronization or batching. Now, the final area for the research is improving  the single packet attack. So my implementation lets you get about 20 to 30 requests into  one packet. And if you get more than that, the operating system just puts them in another  packet shortly later. And I'm certain you can fit a lot more requests into a single  packet with enough effort. You can totally do it with a custom TCP or TLS stack and there  may be other easier ways of making it happen that I didn't think of. I didn't try to push  that side of the research that far because 20 requests is enough to cause a lot of damage  in the wild by itself. The other thing that would be really valuable on that angle is  other ways of causing server side delays because that will let you trigger staggered  attacks more reliably and it will also help out with the timing attack side a little bit  as well. And more generic techniques would be especially valuable there.  Now one final word of advice. This is a slide just for DEF CON and this might be a controversial  take. We'll see. Now in this session I've tried to squeeze six months of research into  the space of 40 minutes. And one thing that can get lost in that condensing process is  how big the gap can get between exploiting something and actually understanding it. So  for example, that GitLab vulnerability, I exploited GitLab.com successfully in I can't  remember, but I think maybe two days. Whereas when I built my own local replica for the  live demo, it took me so I could get the token to be misrouted, but the token was never ever  valid. I like ran attacks running every ten seconds for weeks and it was never valid.  And it took me over two months to figure out why that was happening and gain the understanding  to actually replicate it successfully. And similarly, I've mentioned timing information  can be really valuable, but front ends can do all kinds of different things with your  requests which can cause other timing delays and massive timing red herrings. Now you can  recognize that behavior and work around it, but what I'm getting at is with this bug class  you will encounter things that don't make sense. And that's absolutely fine. My advice  is just to embrace the chaos. Normally I would say you should understand a system and then  use that understanding to exploit it. But with race conditions there's a risk that that  limits you to finding vulnerabilities that make sense. And in my experience, the coolest  race conditions make the least sense. In other words, it's nice to have an explanation, but  all you really need is an exploit. Now for defense, when a single request can push an  application through multiple invisible substates, understanding that application and predicting  its behavior is incredibly difficult. And defense is just not practical. So my advice  is try to eliminate substates entirely. Like the effects of each request should be atomic.  You can achieve that generally using your data store consistency features and another  thing that will help with that is avoid mixing data sources. So device was vulnerable because  they sent an e‑mail to an address from an instance variable but took the contents from  the database. If they took the e‑mail address and the contents from the database, they would  have been absolutely fine. The other key thing is to make sure that you know what kind of  locking system your session handler is using because if it's not doing any locking, that's  bad news. Now there's a lot of further reading available. The three key things I would suggest  are check out the white paper. That's basically the written up version of this presentation.  It does have a little bit of extra info and some different angles on stuff. Have a practice  on our online labs because there's no substitute for real experience with these vulnerabilities  and finally grab my code, take a single packet attack and find some real vulnerabilities  out in the wild. If you have any crazy findings with these techniques that you would like  to share, I would absolutely love to hear all about it. And the three key things to  take away are the single packet attack makes remote race conditions local. With race conditions  everything is potentially multi‑step and to find these bugs, predict, probe and prove.  I'm going to take five minutes of questions now. If you have any more after that, just  come and chat to me at the back or chop me an e‑mail. Thank you for listening.  Any questions? Yeah. Can you use the mic? There's a microphone over there.  In the middle. Sorry.  What severity did GitLab eventually rate that vulnerability as?  So sadly for me, GitLab rated it as medium which I don't think is accurate. I think it's  because I hadn't discovered ‑‑ so when I initially reported that, I didn't discover  the invitation hijacking angle. I didn't realize getting a validated e‑mail would actually  let you do that. And by the time I realized that, it was already fixed and paid out. So  I think if I had originally reported it with that impact, it would have got high whereas  as it was, it was only risky to people using GitLab via the signing with GitLab button  which thankfully not many people are doing. Anyone else?  Thanks for the really interesting talk. You mentioned that frontends and load balancers  cause issues with this sort of thing. And you said there are some workarounds. What  are they? Yeah. They're not all trivial. But you basically  you have to observe what's happening. So you can notice if you send your requests  in a batch and the first request always comes back faster, you can try changing the order  of the requests. And so sometimes by flipping the order, you can fix the issue or just adding  a dummy request at the start. That's one way of dealing with it. But there's like so many  different things that they can do. It's hard to give like a playbook for every kind of  scenario. I think the most important thing there is when you see a delay, don't assume  that that's something that's happening server side. That could just be the load balancer.  So test that assumption before you try and work around it.  Cool. I think that's everyone. Thanks.


url: https://www.youtube.com/watch?v=LfZcS_G-Zcs
title: DEF CON 31 - Small Leaks, Billions Of Dollars - Nikolaos Makriyannis, Oren Yomtov
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=LfZcS_G-Zcs",
    "title": "DEF CON 31 - Small Leaks, Billions Of Dollars - Nikolaos Makriyannis, Oren Yomtov",
    "description": "Multi-Party Computation (MPC) has become a common cryptographic technique for protecting hundreds of billions of dollars in cryptocurrency wallets. MPC algorithms are currently powering the wallets of Coinbase, Binance, Zengo, BitGo, Fireblocks and many other fintechs/banks servicing hundreds of millions of consumers and thousands of financial institutions.\n\nThis presentation examines the most common MPC protocols and implementations and shows that securing MPC remains a challenge for most companies.\n\nWe show practical key-exfiltration attacks requiring no more than a couple of hundred signatures. Namely, we show three different attacks on different protocols/implementations requiring 256, 16, and *one* signature, respectively.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 1988,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   Okay, hello. I'm Nikos. I'm a cryptography researcher at Fireblocks. This is Oren. He's a  security researcher at Fireblocks. And we're here to talk about hacking crypto wallets. So  what is a crypto wallet? So let's say you want to spend bitcoin. You need a wallet. That  wallet holds a key. That key allows you to sign transactions. Those transactions you can  broadcast to the blockchain and send crypto to your favorite people. There's a problem with  the setup because there's a single point of failure. The key is sitting in one place, ready  to be stolen. How can you minimize that risk? You can use multi-party computation, also  known as MPC. So what is MPC? So at a very high level, the idea is that instead of having one  key in one place, the key is split into shares. And those shares reside with different parties.  Actually, MPC promises much more than what the picture suggests because the key is never  assembled in one place. The parties calculate their shares and the public key via an  interactive protocol. And then every time they want to sign a transaction, they run a different  interactive protocol for calculating the signature. So small aside, MPC is much bigger than  the use case I just described, which is threshold signatures. It is the crown jewel of modern  cryptography. Basically, anything you can do with a trusted centralized party, you can do  trustlessly with MPC. There are numerous examples. I'm not going to go into them. But what I  will say is that commercial adoption has been a bit slow. MPC has been around since the  80s. And the most significant use case before blockchain was the famous Danish sugar beet  auction of 2008. And since the advent of blockchain, MPC is now protecting billions of  dollars in cryptocurrency wallets. But we're not here to talk about MPC in itself. We're here  to hack crypto wallets that are based on MPC. So what would that look like? One thing that  could happen is a denial of service. Let's say I'm able to freeze your wallet so you can't spend  your crypto. That's a problem. Something more severe would be signature forgery. Let's say  Nikos and I, we have an MPC wallet. So every time we want to sign, we sign together. So I  tell him let's sign this $10 transaction to your favorite charity. He signs it. But because I  took advantage of some flaw in the protocol, I actually made him sign a totally different  transaction without him knowing. That's bad. But what's even worse would be private key  exfiltration. Whereas by him signing that transaction, he leaked his key share to me. And  now I can sign whatever I want, whenever I want without his consent. Today's talk will be  focused on this. We're actually going to show you three different attacks that all end with  private key exfiltration. When we'll be talking about attacking crypto wallets, MPC crypto  wallets, I want you to have this threat model in mind. So these are a bunch of people  participating with an MPC wallet together. So each time they want to sign, they need to  collaborate. Now one of those participants, namely Alice, will be acting maliciously. Now  either she woke up one day, decided to be evil, or maybe she was compromised by an attacker  and now is using her identity to attack the other people. So whatever her motivation might  be, she wakes up in the morning, her only goal would be to exfiltrate the other counterparty's  key shares. And she will do that by signing normal looking transactions with them. So the  research findings that brought us here today were as followed. We have discovered four novel  attacks, including three zero days. These findings have affected over 16 different vendors and  our open source libraries. We'll be releasing at the last slide four fully working proof of  concept exploits for these attacks we'll be showing you. We actually used the very same  proof of concept exploits against two vendor production environments and got the private  keys. And the last thing I want to stress is most of our attacks are not implementation  specific. We'll be attacking MPC at the protocol level. So the affected parties were  numerous. Some of the biggest crypto wallets were affected, a number of crypto custodians  were affected, the most popular consumer MPC wallet was affected, as well as some of the most  popular open source MPC libraries. The attacks we'll be covering today will start with  attacking the most popular two party signing protocol. It's called Lindle 17. Carrying out the  attack will be somewhat high interactivity required. Then we'll go to a second attack. We'll  attack the most popular multiparty signing protocols, the GG18, GG20 family of protocols. And  last but not least we'll attack what we call a do it yourself protocol because it doesn't  really closely adhere to any academic paper. Okay, so before we have a look at the  exploits we need a few items of background material. The first item in the background is the  math. Thankfully no math, I mean no advanced math. The only thing, we're not going to be  talking about elliptic curves or abstract groups. The only thing you need to know for today  is the modulo operator. What is the modulo operator? Well, very simply X modulo N is the  remainder of X divided by N. For example, 5 modulo 5 is 0 because 5 is divisible by  itself and 6 modulo 5 is 1 because 6 is greater than 5 and there's overflow and yada yada  yada. Great. Second item in the background is homomorphic encryption. This is a cool thing. So  what is it? It is a special kind of encryption that allows computation on encrypted data.  Without decrypting the cipher text, that's very important to note. So for example, let's  say Alice sends an encryption of the number 42 to Bob. So here and throughout the talk we  will be using color coding. Red for values that Alice knows, blue for values that only Bob  knows. So Bob receives this thing and he can operate on it. For example, he can multiply by  the number 2 and he can add the number 100. He does this obliviously without knowing what's  happening inside the cipher text. Alice, after receiving the resulting cipher text, can  decrypt it and learn the result without ever knowing what Bob exactly did to the cipher text.  So there are many kinds of homomorphic encryption. I'm not going to dive into them today but  we will be looking at the most vanilla kind which is parameterized by a public key, N. This  is a number and it's the product of two big primes. This detail will become relevant later in  the talk. So the last item in the background is the ECDSA signature scheme. This is the most  important signature scheme in the blockchain space. It is used by Bitcoin, it is used by  Ethereum, among other blockchains. And the protocols we'll be looking at implement this  scheme. So how do you uh generate an ECDSA signature? It goes something like this. First you  sample a random number K. This is a secret and it is chosen afresh with each signature. It is  also called the ephemeral key. Then to calculate the signature, you simply compute a function of  the message to be signed, the ephemeral key, the private key, as well as an ECDSA constant that  everybody knows that we denote by L. So that's for one party. What about multi-party? What  about two parties? Well the idea that we've already alluded to at the beginning of the talk is  that instead of having the secret material residing in one place, the secret material will be  split between the parties. Okay so having covered the background, now we can move on to our  first exploit. We will show you how to compromise the LIDL 17 protocol implementations of the  LIDL 17 protocol. And uh in order to explain how to compromise it, I need to tell you what the  protocol is. So it goes something like this. So first there's a key generation phase where the  parties choose uh random key shares. So that would be X1 for Alice and X2 for Bob. The next step  in the key generation is for Bob to encrypt his share under a homomorphic scheme that he  controls. And he sends that encryption to Alice. So he sends an encryption of X2 to Alice. I  will remind you that only Bob can decrypt this thing but Alice can operate on it. And this is  going to be important for signing. So before we move on to signing, we need to address the  elephant in the room. This is a cryptography talk. So there's going to be formulas involved.  But nothing bad is going to happen. Oren will take care of you. Okay so let's have a look at  signing. Signing goes something like this. So Alice uses the cipher text she receives from  Bob during the key generation to send an encrypted partial signature to Bob. The partial the  encrypted partial signature looks something like this. And the only reason I am displaying  this formula is to show you that we have almost all of the ingredients for the ECDSA signature  scheme. We have the X's, we have the message, we have K1, we have the ECDSA constant L. The  only thing that's missing is K2. So how do we, how does Bob finalize this thing? So he  simply decrypts this value, multiplies by his contribution to the ephemeral key, and reduces  everything modulo L. At this point, he checks whether this thing is a valid signature. Why  does he need to do that? Well he does this because you know, maybe Alice fell asleep while  during the signing process and she forgot to multiply by her K1. At this point, Bob will fail  to verify that the signature is valid and Alice will be notified of this either because Bob  tells her or because the signature never made it to the blockchain. So what happens in this  case? Well to answer this question, we consult with the paper the protocol is based on. And  the paper has a very interesting assumption, not assumption, instruction. It says any  abort will result in no, will imply no later execution. Which means that if Bob detects an  invalid signature, the wallet must be locked. Putting our adversarial hats on, we see this  and we think well, maybe we can leverage this into a denial of service attack. Maybe we can  act as Alice and send some garbage nonsense partial signature to Bob and now the wallet is  supposed to be locked, right? So we went on to code this. We found some open source  implementation of the Lienvendel 17 and we tried to do this. To our surprise, nothing happened.  Basically we tried again and again and the wallet was never locked. So we were kind of  devastated by our failure to mount some denial of service attack and we went back to the  drawing board. We're trying to understand, wait, if this assumption, this instruction is part  of the paper, why is it there in the first place? So the paper is actually very clear about  why it's important. It says the only problem is that Alice may send an incorrect partial  signature to Bob in which case the mere fact that Bob aborts or not can leak a single bit  about Bob's private share of the key. Now taking this intuition and like taking it to its  logical conclusion, we might think of a hypothetical attack that looks something like this.  First Alice would craft a malicious signature that would fail to verify depending on a single  bit of Bob's key share and then she will see if it verifies or not. Then she can do this again  and again and again every time by seeing if the signature verified successfully or not knowing  if that specific bit is 1 or 0. 256 signatures later, bam, she has the entire key share of  Bob. She can combine it with her own and sign away without his consent. So this is very easy  to do in PowerPoint with pictures but to actually get the math to do this you need a  cryptographer like Nikos. So that's where we stopped relying on the paper and we had to  think for ourselves. And what we did is we had a long hard look at the partial signature that  Alice sends to Bob. And we tried to mess around with it. We tried to like, you know, tinker  with the X. We tried to tinker with the message. Nothing happened. We tried to tinker with  the K. Again nothing happened. But then the crypto gods smiled on us because we had the  following uh, breakthrough. We realized that if Alice switches the modulus, so instead of  using the L parameter of ECDSA, she uses the N public key of the homomorphic encryption  scheme. These 2 values are equal after Bob decrypts if and only if X2 modulo K1 is equal to  0. So I will spare you the mathematical mumbo jumbo and I will give it to you in a picture.  Basically when Alice switches the modulus, the following thing happens. If the signature is  valid, X2 is divisible by K1. And I will remind you that K1 is the value that Alice controls  and she knows. If the signature is invalid, then X2 mod K1 is not equal to 0. And this is,  this is very good for the attacker because this already gives a way to learn the least  significant bit. Why? Because Alice can simply set K1 equals 2. In this case she mounts the  attack, she switches the modulus, and she obtains leakage X2 modulo 2 equals 0 or not. And  this is exactly Bob's least significant bit. Okay, so that's one bit, but what about the rest  of them? So for the next bit you can use the next power of 2, namely 4. When you mount the  attack, you obtain leakage whether 4 is, whether X2 is divisible by 4. So this is great  leakage if X2 is already divisible by 2. Because if not, then the leakage that you actually  want is X2 minus 1 is divisible by 4. And to obtain this leakage, well what you need to do  is you need to do some math. You need to massage the algebra. You need to add an offset to  the partial signature in order, an offset that depends on whatever you already know of Bob's  key. And this will give you the leakage that you actually want. So to summarize, in order to  exfiltrate the ith bit, you set K to be the ith power of 2. You offset the partial, Alice's  partial signature by a value that depends on whatever you already know about Bob's key. And  in the end, depending on whether the signature fails or not, you obtain leakage, the ith bit  of Bob's key share. We didn't leave it at this, and we wanted to see if it would actually  work. So we went out, we found the most popular open source implementation of the  Lindell 17 protocol. It was published by Zango. And we tried to see if we could make it  work. So this is how the POC looks when it's run. As you can see on the right hand side of  the screen, every signature leaks us a single bit of Bob's private key share. Depending  whether the signature failed or not, we know whether it's 1 or 0. We only need to do this  256 times. Now it may sound a lot, but it only takes a couple of minutes. And bit by bit, we  leak his entire key. Now we can combine it with our share of the key, and we have the  entire private share. We can print it in hexadecimal format, load it to Metamask or your  favorite crypto wallet, and you're done. So we've disclosed this to all the affected vendors  and they've since mitigated it. How did they do that? Well, they simply followed the paper's  specification. So like after you see that there was a failed signature, just don't sign  again. Now this works, right? It mitigates the attack. But there are also other ways that you  might want to do it where you don't get a possibility of a denial of service attack. And to  explain a possible way of doing that, we need to introduce a new cryptographic primitive. It's  called a zero-knowledge proof. What is a zero-knowledge proof? Basically it's a proof that  yields the validity of a statement and nothing else. So to illustrate with an example, let's  say Alice encrypts some number X along with a zero-knowledge proof that that number is within  some range, for example 1 to 42. Now Bob can receive this and verify the zero-knowledge proof  and be certain that what he has is indeed an encryption of a number between 1 and 42, but he  knows nothing else. Only what the zero-knowledge proof wanted him to know. So taking the  intuition of this thing, we could maybe add a zero-knowledge proof to the protocol in order to  make sure that Alice cannot deviate from calculating the partial signature in the way the  protocol says she needs to do. Well, congratulations. You've learned how to compromise  implementations of the most popular two-party signing protocol and also how to mitigate it.  And we're on to our second attack of the day, which is attacking the most popular multi-party  signing protocol, meaning it can be two parties, three parties, or a hundred even. So this has  affected many vendors and open source projects. So when we talked about the Lindell 17  protocol, we actually explained how it works, like start to finish. But the Digi protocols, the  thing with them is they're very complicated. They actually, to sign, they require between  seven and nine rounds of communication. So we don't have time to explain all that, and  actually we don't even need to because the entire thing happens during the very first round.  The very first round implements what's called a multiplication to addition. So let's dive into  that. What is it? It's a way to transform two multiplicative shares, K and X, into two  additive shares, alpha and beta, where this equation applies. So how does the paper say that  you could do that? It says that Alice needs to encrypt her multiplicative share, K, along with a  zero-knowledge proof for doing just that, and send it over to Bob. Bob now can operate on  this homomorphically encrypted value. He doesn't know what it is, but he can multiply his  multiplicative share, his X, his key share, and to make sure that Alice doesn't learn anything  about his X, because that would be terrible, he adds a mask to mask it. Now Alice decrypts  this, she gets alpha, Bob gets beta by being equal to minus mask, and as you can see, it so  happens that K times X is equal to alpha plus beta. There's one very important thing that we  need to know about this. In the case of ECDSA where X and K are 256 bits, the mask needs to be  sufficiently large. It needs to be bigger than 512. Now why is that? To give an intuition of  how this masking works, we're going to use some visualization of small numbers. Let's say we  didn't even use a mask. If Alice would decrypt and get this value, X times K, she knows K,  right? She could just divide it by the K she knows and get X in the clear. So that's why we  need that mask. Now adding the mask actually works. It masks it. Although she knows K, she  doesn't know the mask, so she can't learn anything about Bob's X. But what happens if that's  not the case? What happens, for example, if K is even larger than the mask itself? In this  case, we can see that adding the mask actually hides nothing. Like the most significant  bits leak X in the clear. Now this could be a really great attack, right? Like we could be  Alice, we could choose a really big K that's larger than the mask, send it over, decrypt this,  and get everyone's key share in one go. But remember that zero knowledge proof that I  mentioned that she's sending over, it actually also includes what's called a range proof. What  that is, it's a zero knowledge proof that ensures that the number K is no bigger than 256  bits, which kind of foils our entire plan of attack here. So we're going to get deeper into the  math of the zero knowledge proof. Hold on tight. How does it look like? Basically it's a  bunch of numbers. The number Z is the one that we'll be focused on, because that's the one  that relates to the range proof part of the proof. Now how is Z calculated? It's equal to W,  which is a small random number, plus K, which is the number Alice is trying to prove is  sufficiently small, times a hash that depends on W, everything modulo N. Now when Bob  receives this, he does a bunch of verifications over the other parts of the proof that we're  not going to touch on, and he makes sure that Z is small. Now as you can see, if K will be too  large, then Z will not be small enough and will fail the range proof part of the proof. Now I  just want to stress that Alice has to follow this specific formula for calculating Z, because  if she doesn't, some of the other verifications will fail. So how can we go about cheating in  this zero knowledge range proof while adhering to this formula of calculating Z? What we're  going to do is we're going to focus on this part of the equation, and we're actually going to  try and zero it out. If we somehow manage to zero it out, then it doesn't matter how big K  is, Z is only equals to W, which is a small number, and we can use whatever big K we want  and pass the verification. So how will we do that? We're going to use what's called the  Chinese remainder theorem. For this use case, because as Nikos mentioned earlier, N is a  product of two primes, P and Q, if this value we're trying to zero out, modulo P and modulo Q,  they both zero out, then it also implies that the value we're trying to zero out zeroes out. So  we're going to use this lens of looking at it, and we can try to zero out the left-hand equations  one by one, and by doing so, we'll achieve our goal of zeroing out the right-hand equation. So  one by one, we start with the first one. It's actually surprisingly simple, because Alice is  free to choose whatever K she wants. How about she chooses K to be equal to Q, right? Then by  definition, Q mod Q zeroes out, and we're halfway there. The easy half now. So how do we go  about the second part? How do we zero out this value modulo P? What happens if this hash that  depends on W happens to organically land on a multiple of P? Well, that would be fantastic,  right? So is it likely to happen? No, but what if we brute force W, such as the hash that  depends on it happens to be a multiple of P? Is this feasible, you might ask yourself. The  question is, no, it's not at all feasible, because the paper says that N needs to be 2,048  bits, which makes P and Q both over 1,000 bits. Now that's impossible to brute force, and if we  could brute force that, right, we might as well just brute force X, which is 256 bits. So what  can we do? How about during the key generation phase, which happens once per wallet, Alice,  instead of choosing N to be comprised of two equally sized prime numbers, she would choose N  to be comprised of two very asymmetrically sized prime numbers, whereas P can be as small as 16  bits, which is brute forcible in an instant, and we can have Q to be sufficiently large to make  up for the desired size of N. Now, some of you might be thinking, well, maybe the protocol  says that there's zero-knowledge proof to prevent us from choosing such an N. It turns out that  there is no zero-knowledge proof that prevents us from using such an N. There is no ZKP for no  small factors. The only thing that the parties check is whether N is square free, and I'm not  going to get into the technical definition of square freeness, but it sounds like, you know, we  have a way, we have a hook, we have a way to get the goods. We can inject this N with a very  small P, then we can choose K to be equal to Q, then we can cheat in the range proof, and then  when we receive the MTA response, we can get all the Xs in the clear. So, are we done? Not so  fast. Because, remember the MTA formula? So this is what Alice obtains during the MTA. Well, in  reality, there is a pesky modulo N operation happening there implicitly, and it's  unavoidable. I'm not going to get into why it's unavoidable, but it's unavoidable. And it's very  annoying for the following reason. K is now almost as big as N, and what happens to the  leakage when K is almost as big as N? So, let's have a look at K times X plus the mask. Here  we see the beautiful X and the most significant bits in the clear. However, as soon as you  apply the modulo operator, the most significant bits of X, they disappear, they jump off a  cliff, they go bye-bye. And the only thing that remains is a small leakage of X. How small?  What Alice obtains using this attack is X mod P, and P is a 16-bit prime. If only there were a  way to obtain X from such remainders. Worry not, Nikos. Once again, the Chinese remainder  theorem comes to our rescue. Now, let's explain how it works a bit more in depth. Let's say we  have this small number, X, which is 23, right? We can encode it in a myriad of ways. Like we  can all see on the screen, we can encode it decimally, we can also encode it hexadecimally. We  can actually also use CRT to encode a number. Now, how would one go about doing that? You  need to divide this number by a few small primes and save the remainder. Now, just using this  information, the primes and the remainders, you can feed them into CRT to reconstruct the  original number fully. Now, it looks a bit like magic, but it also has some limitations.  Namely, it would only work to encode a number that is smaller than the product of the  primes. In this example, using the primes 3, 5, and 7, you could only encode a number as big as  105. We're trying to encode a number as big as 256 bits. So to do that, we'll need 16 small  primes that are each 16 bits of size. So if we can get these 16 reminders by the leakage that  we explained earlier and feed them all into CRT, we have Bob's key share, right? That could  work. Anything stopping us? Yes. We only have one N. Remember, while K is chosen afresh  during every signature generation, N is chosen once per wallet during the key generation  phase. So we only have one P value, so we can only do this to achieve the very first leakage.  So, bear with me. What if during the key generation phase, Alice, instead of choosing N to  be this handsome-looking value that is a product of two primes, she would choose N to be this  monstrosity that is a product of 16 small primes plus times a prime that is as big to make up  for the desired size of N. Well, some of you might be wondering, well, isn't there some zero  knowledge proof in the protocol to make sure that you can choose this monstrosity? It turns  out that there is no zero knowledge proof for checking the biprimality, because the only  thing that the parties check is whether N is square free, and I'm still not telling you what  square freeness is. So, we're at the finish line. We can extract all of these moduli by  injecting the N and then choosing the K and then cheating in the range proof and then obtaining  the leakage. So how does it work? Well, when we have the normal-looking N, we set K equals Q  and we obtain leakage X mod P. Now that we have the bizarro N, we set K equals N over P  I and we obtain leakage X mod P I, and we need to do this in 16 different signature  generations, 16 different signature sessions. In the first one, we're going to use the first  K. It's going to give us X mod P 1. In the second one, we're going to use the second K. It's  going to give us X mod P 2, and so on and so forth until we get the 16th leakage. We feed  everything into the CRT algorithm, and we obtain X in the clear. So, once again, we went to  see if this crazy idea would work. We found an open source implementation of the GG20 protocol,  and we gave it a try. So, we start by choosing 16 small primes to make our bizarro N, and then  we start signing. Each time we choose K, we cheat in the range proof, and we get the  desired leakage. Now, we need to do this. We need to sign 16 times, each time getting one  of those leakages, and then we can feed all of this information into CRT. Once again, combine  it with our own key share, and we can print the full private key in a beautiful hexadecimal  format, load it up, spend away, no need for consent of any of the other parties. Once again,  we've notified all the affected vendors. They've since mitigated this attack. How would you  go about mitigating such an attack? Well, you could add those zero-knowledge proofs for  making sure the well-formedness of N, so Alice can choose this bizarro N that is needed to  carry out the attack. Well, congratulations. We're done with the second attack. We're on to  the third and last. Great. So, in the last few minutes, we will show you how to compromise  what we call a do-it-yourself protocol that we found in the wild. For this protocol, we will  be exfiltrating the key in a single signature. Actually, we're going to do that in less than a  signature. We're going to do it in the first round of the first signature generation. So, what  does the protocol look like? So, it is also an MTA-based protocol. However, here, there are no  zero-knowledge proofs accompanying the ciphertext that the parties sent to each other.  Furthermore, the mask now is chosen to be as big as N. And this is important because now our  previous attack is no longer relevant. Because it doesn't matter how big K is, what's inside  the encryption is always hiding the X. Okay, so what can we do about it? Well, we can do a lot  about it because without the zero-knowledge proof, Alice can send something that's not even a  ciphertext. She can send, for example, the value 4. In doing so, and by choosing a carefully  crafted N, specifically one that is not square free, Bob will inadvertently send back his X in  the clear. Actually, it's not exactly in the clear. You need to do some data processing and  there's a bunch of primes involved and you need to do CRT and then you need to brute force a  bit. But everything happens in seconds. All right, so you can think about this attack as a  condensed version of the previous one. Whereas instead of getting the 16 leakages in 16  signature, we get all of them in one signature, do the brute forcing offline and then use CRT  to reconstruct the key. Now, this demo is going to go fast so do not blink. We start the  signing, we do the MTA phase, we get the leakage, we do the brute forcing, we fit it all into  CRT and voila, we have the private key. To conclude, we've shown you a bunch of different  attacks on MPC protocol that all result in exfiltrating the private key which is bypassing the  basic promise, security promise of the MPC protocols. I hope that you might find this as  interesting, as exciting as we do because this is a new space. The cryptography is really  interesting and it could really use as many researchers, as many smart people's eyes looking  over making sure everyone is implementing this stuff correctly. Here you can find all the  proof of concept source codes that we've showed you today as well as a technical white paper  explaining the math in more depth than you could have ever dreamed of and thank you very  much for coming. Thank you.


url: https://www.youtube.com/watch?v=gCVTbfDecwI
title: DEF CON 31 - Prototype Pollution Leads to Remote Code Execution in NodeJS - Shcherbakov, Balliu
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=gCVTbfDecwI",
    "title": "DEF CON 31 - Prototype Pollution Leads to Remote Code Execution in NodeJS -  Shcherbakov, Balliu",
    "description": "Many have heard about Prototype Pollution vulnerabilities in JavaScript applications. This kind of vulnerability allows an attacker to inject properties into an object's root prototype that may lead to flow control alteration and unexpected program behavior. Every time a successful exploit looks like magic or is limited to a denial of service (DoS). Would you be surprised if I told you that every application has a chain of methods that can be triggered by Prototype Pollution and leads to arbitrary code execution? Such gadgets populated Node.js core code and popular NPM packages. Keep calm. Not every app can be exploited! However, this fact increases the risk of exploitation many times over.\n\nIn our research, we studied Prototype Pollution beyond DoS and analyzed Node.js source code against the gadgets. We then analyzed 15 popular Node.js apps from GitHub and got 8 RCEs. Through this talk, I will elaborate on the detected gadgets and vulnerabilities. We will also take a look at how the recent changes in Node.js mitigate these issues.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 1217,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   Hello everyone. Thank you for warm introduction. So, I was so nervous before my first DEF CON talk  that I prepared 62 slides for this 20 minute talk. We will try to manage it. So, we'll talk  about Prototype Pollution Vulnerabilities in JavaScript. This talk is based on the joint work  with Musar Balio and Chris Steichel. In this paper we study Prototype Pollution Vulnerabilities  and their gadget and implemented the tools to detect them. I already presented part of  this talk, the exploits that we detected in the real application and details of the gadget  on Black Hat Asia. Today I want to present more details about our methodology, about the tools.  Let's start with some introduction in JavaScript and how inheritance work in JavaScript.  So, we run Node.js which executes the code in index file. The first line of the code creates  an empty JavaScript object. The runtime allocates a new object with a built-in property proto  that points to the object prototype. The object prototype has a bunch of functions that we can  reuse. For example, toString. To implement inheritance, JavaScript allows to extend the  prototype with a new property. In this example, we define the property x with value 42. Things  get more interesting when we create some other object, in principle unrelated from the first  one. Both objects share the same prototype. When the runtime executes the last line of the  code to print x property for the second um, object, it tries to find prototype in the object  itself. Since x is undefined for the second object, the runtime will look up the property x  in the prototype. In this case, um, it prints 42 to the terminal. Well, let's consider the  threat model of web applications to see how this feature can affect uh, security properties of  the application. Index.js file creates a simple web app that handles two requests, update and  backup. The attacker in our threat model can send any request to the server, for example, update  with any parameters. Let's see what happens when the parameters are in this figure. The code  creates an empty object, it reads proto property, and then the attacker adds uh, the property  shell, uh, with the value calc to object prototype. On this, so this code pattern is called  prototype pollution vulnerability. But how can it affect our application? Let's assume that  this code handler handles backup request. It just executes backup script by the helper  function. Notice that the attacker cannot control any arguments of this helper function. In  this function we can give some options in terms of which shell you want to use. Uh, if we  don't specify this option, it will use the default shell. And then, um, it will run a new process.  If the attacker sends backup request after prototype pollution, we execute the function and  options dot shell reads the attacker controlled property from the prototype and runs the  calculator. So, we get remote code execution and this code fragments uh, call it prototype  pollution gadget. If you find gadget in the code of Node.js itself, the impact is much higher  because it potentially affect of all applications. In summary, to achieve remote code execution,  we need two steps. Identifying prototype pollution and identifying gadgets. How to identify  prototype pollution in scale. We implemented static analysis for Node.js applications and uh,  NPM packages. We used stint analysis where we marked the attacker controlled data by the input  uh, label. Uh, however, we cannot define this thing syntactically because not every property  assigned uh, uh, not prop- not every property assignment uh, leads to prototype pollution. Uh,  instead we use uh, what we call multi-label paint analysis to find this thing. Let's see how it  looks uh, at this example. We assume that all arguments uh, of the function are attacker  controlled. Uh, and mark uh, them by input label. We propagate the input label and if we have a  property read with the tainted property name, we change the prototype to proto. It means  attacker can potentially read pro- uh, object prototype um, here. When the analysis detects the  property assignment with receivers that has a proto label, like this one, it reports the code  fragment as potential prototype pollution vulnerability. This is the main idea of our  analysis. We implemented it based on the code QL um, ana- analysis framework. Uh, and uh, it will  lead that uh, our analysis on one hundred vulnerable packages uh, that we collected. The best  result achieves ninety-seven percent recall. It means we uh, detected ninety-seven uh,  vulnerabilities out of one hundred. And uh, which is necessary to find vulnerabilities in the real  applications. The second question is how to identify the gadgets. We analyzed Node.js code um,  and uh, used dynamic analysis uh, to detect property reads from object prototype. Uh, then we  used static analysis to find flows from these properties to internal Node.js function calls. You  can find all details of this analysis in the paper. In presentation I want to show some  interesting results. So, we detected eleven different gadgets in Node.js APIs. The first gadget  is spawn function which execute new process. Uh, let's look at this code. Details is not  important uh, here. But we see that the property shell and the property end can be uh,  undefined. And there is a flow from these properties to the internal function call. Uh, which  is actually vulnerable. It's simplified version of uh, spawn function from Node.js API  implementation. Let's see how remote code execution can be achieved. Suppose that the backup  handler calls spawn with no attacker control at arguments. The attacker first follow the  prototype by update request as we saw earlier. They add property shell with value node to object  prototype. The property end by another request. And send backup request to execute spawn  function. Let's see what happens. When spawn executes, it reads uh, the value of the shell  and end from the prototype. It allows attacker to run Node.js in debugging mode by  controlling environment variables. And connect remotely to execute arbitrary code. For this we  implemented uh, the shell based on Node.js uh, remote debugging protocol. Uh, you can see the  short demo on the slide. The second gadget is the require function. The require function is  used to include external packages to an application. So each application uh, has a lot  require calls. Uh, this is simplified snippet of require function. As we can see it reads a  package configuration file, package JSON. And to release the entry point uh, if this is  defined in the property main. If main is undefined, Node.js use a default value. Let's see how we  can exploit it if the attacker pollute the main property. To exploit the gadget, we need to  require a function call for a package without the main property defined. An example of uh,  such um, a gadget is bytes. One of the popular gadget in NPM um, ecosystem. Let's see how it  works when the attacker triggers this code to execute the uh, require call. The attacker  triggers the backup handler which parse a config file of byte package. Since the main  property is undefined, it lookups uh, the property from the prototype. To achieve remote  code execution, attacker should control this malicious file. As you can guess, this is a  strong requirement. Uh, the attacker should be able to upload some malicious file to the  system. For example, using some another vulnerability. Let's see how we can bypass this  limitation by combining these two gadgets. The key idea is to use require gadget to trigger the  spawn gadget. To achieve this, we need to find the existing file that execute spawn function.  If we identify a file in Node.js default distribution, then we increase the impact of the  exploit because every application uh, use Node.js already have this file. An example of such a  file is NPM.js which uh, runs Node instance. Let's look at the end to end uh, execution.  The attacker exploits the main property with the path to NPM.js and the end property as  required uh, by spawn gadget. Finally, when backup is triggered, uh, Node.js uh, executes the  require function, loads NPM.js that calls spawn function. The spawn function reads the attacker  controller environment variable from the prototype and runs Node.js in debugging mode as we  saw earlier. So that attacker achieved remote code execution for require call without  additional requirements. The last question is how to exploit real application using or tools and  detected gadgets. Uh, we covered uh, the GitHub uh, for Node.js applications and took 15 uh,  most popular ones. We ran our tool and got some prototype pollution cases. As you can see the  prototype pollution pattern is rare in practice and manual verification is applicable for the  total number of detected cases. We confirmed eight detected cases uh, as exploitable and  reported them to maintainers. You can see we found two cases in NPM CLI. Everyone I think  uses up uh, package uh, parserver and uh, rocket chat uh, messenger. The main problem is  um, real exploitation of this um, vulnerability to achieve remote code execution. It's uh,  that code of um, um, some code of the application can breaks your application if you pollute  object prototype. So the code does not expect any additional properties in the object  prototype. Uh, it kept many times uh, in this experiments and I want to show one technique that  I used um, and that you can also um, apply for your research. Let's see a case for parserver. We  have a parserver. It's a service that provide REST API out of the box and use some database.  For example MongoDB to store data from the request. Uh, it also use uh, JSBSON. It's a library  of the MongoDB that uh, can serialize and deserialize the data to binary MongoDB format. So we  detected prototype pollution case in parserver. Uh, this example of the code details is not  interesting uh, what's uh, it's not important. What's um, actually important for us that  attacker can control uh, name and uh, the value of uh, the polluted property. We also detected a  gadget in JSBSON um, package. And this gadget can be triggered when JSBSON deserialize some  data from the MongoDB. So this gadget call evolve function for function string from the MongoDB  that attacker can store uh, to the MongoDB before. Uh, but the problem that this evolve call  executed uh, only if evolve function option is enabled. As you can guess it's disabled by  default in the configuration file. But it can be um, polluted uh, and the gadget reaches from  the polluted prototype and we can enable this feature in run time. This is the main idea. So let's  see on the naive way how we can exploit it. Attacker first send a package that should trigger  prototype pollution vulnerability. The package uh, serialize it to the MongoDB uh, response  deserialize it and trigger prototype pollution. Good. We pollute uh, the option that we need to  trigger a gadget. After that the attacker send a package that should trigger a gadget but  serializer of JavaScript BSON library throws an exception and application crashed. It looks  like unexploitable case. We cannot send any request after prototype pollution. Application  crashed after the first request that we tried to send. How we can bypass it? I hope you  found a way, some kind of race condition. Let's see. If the attacker sent the package that  trigger remote code execution gadget first, this package uh, serialize it and MongoDB start to  handle it for the some long time. At this moment the attacker sent second gadget that should  trigger prototype pollution vulnerability. It's serialize it and deserialize it from the  MongoDB and successfully trigger prototype pollution. After that MongoDB decided to stop  handling the gadget uh, the first request and uh, pass it to the application. And we trigger  remote code execution. This technique I used many times. Usually you need to very short uh,  time gap to trigger uh, remote code execution gadget. One of the techniques that I use I just  send um, like 20, 50 request to trigger remote code execution and one request that trigger  prototype pollution in the middle. Most likely we get some situation that we trigger remote  code execution uh, exactly after prototype pollution in the some thread. Okay, let's see how  it looks in, in practice. Some short demo. We run parse server. We need to implement a  script to um, to exploit this vulnerability because uh, the second request we need to send in  uh, 100, 300 milliseconds after the first one. So it's not possible to do manually. Uh, so this  script prepared database to add some data to MongoDB to make it a little bit slower to handle  the first request for the long time and send these two um, requests. And you can see that we get  calculator from the parse server. So it works. So, in conclusion, uh, we implemented and  open-sourced uh, tools to detect prototype pollution vulnerabilities and their gadget. Uh,  detected 11 new gadget in Node.js APIs. You also can find them uh, in the GitHub repo. Uh,  some gadgets already fixed it, but not all combination of that. And we reported a uh, remote code  execution um, vulnerabilities in the popular open-sourced applications. So the interesting  question for the future work. One of that, what is the more efficient way to detect gadget? So  we have options like a static analysis, dynamic analysis, we already use some hybrid approach. I  think it's a good question for the future research. How many new gadget in uh, NPM packages?  We did not consider in this research NPM packages, but it's also a large uh, surface for the  gadget. How many new gadget in Node.js APIs source code? If we find some efficient way to uh,  to detect it, to explore it, probably we can find some new ones. We continue research in this  direction. If you're interested um, in this, just follow me on the Twitter. And thank you for your  attention.  Applause


url: https://www.youtube.com/watch?v=v0fraChyonQ
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
title:
  DEF CON 31 - Second Breakfast Implicit & Mutation Based Serialization Vulns in  NET - Jonathan Birch

content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=v0fraChyonQ",
    "title": "DEF CON 31 - Second Breakfast Implicit & Mutation Based Serialization Vulns in  NET - Jonathan Birch",
    "description": "Exploits of insecure serialization leading to remote code execution have been a common attack against .NET applications for some time. But it's generally assumed that exploiting serialization requires that an application directly uses a serializer and that it unsafely reads data that an attacker can tamper with. This talk demonstrates attacks that violate both of these assumptions. This includes serialization exploits of platforms that don't use well-known .NET serializers and methods to exploit deserialization even when the serialized data cannot be tampered with. Remote code execution vulnerabilities in MongoDB, LiteDB, ServiceStack.Redis, RavenDB, MartenDB, JSON.Net and the .NET JavaScriptSerializer are all demonstrated. Techniques to both scan for and mitigate these vulnerabilities are also discussed, along with methods and obstacles for exploiting serialization in .NET 6+.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2104,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   So this is second breakfast implicit and mutation based  serialization vulnerabilities in dot net.  I'm Jonathan Birch, I hack office for Microsoft.  And if you want to talk to me about this presentation,  oh.  I'm Jonathan Birch, I hack office for Microsoft.  If you want to talk to me about this presentation  or anything else security related,  please contact me on Mastodon.  In this talk I'm going to explain  remote code execution vulnerabilities  I found in several dot net NoSQL engines.  I'll talk about what I'm calling  a mutation based serialization vulnerability.  I'll explain how you can bypass serialization binders  and how you can defend against all of that.  Also some bonus stuff just for DEF CON at the end.  So a lot of my day job is doing security design reviews.  I have a bunch of meetings every week  where I'm looking at data flow diagrams,  telling people do it this way instead, that kind of thing.  And something I do in those meetings anymore  to sort of add value is I'll just open up the repo  that I've never seen before and spend like a half hour  while I'm talking to them,  figuring out what are the actual vulnerabilities here  so I can talk to them about that too.  And so the research that led to this talk  happened because last fall I saw an article  on a certain orange colored website about LightDB.  And it's a dot net open source library  for a NoSQL engine.  I thought, okay, you know, I'll just go do  a security review of their repo.  And so when I did that, I saw this code.  And what jumps out to me in this code specifically  is this line, this call to type get type  that's being passed a string.  And to me at least, that's a really bad sign.  But why is that a bad sign?  So type get type in dot net is used to convert a string  that's like the name of a dot net type  into an actual type object.  And what that means is that someone's going to be  giving you the name of a type,  generally for an object you're then going to create.  So they're telling you what kinds of objects  you're creating, which means they're telling you  essentially what code you're going to run.  And that means that if someone malicious comes along  and they give you a malicious type name  and you're running malicious code.  And so how does that show up in LightDB?  Well, LightDB is a NoSQL engine  and generally when an application is using it,  it's just saying to LightDB, store this object I've got  and maybe at this index with these properties,  that kind of thing.  And what LightDB is doing is it's going to put that  in a file so it serializes it with a serializer  called bsonMapper into a bsonStream  and stores that bsonStream in a file.  And when the application wants the object back,  it deserializes that bson back into an object again.  So bson is just a binary encoding of JSON.  So you can take that file LightDB makes,  decode it back into JSON.  And if you do that, it looks about like this.  And if you look at this JSON here,  it's got this underscore type key in it.  And after that, it's got the name  of an actual dot in that type.  So what LightDB is doing with type get type  is it's taking that type name,  it's passing it to type get type  to actually create the object during that deserialization.  So the data in that bson is telling LightDB  what types it's going to make.  And that means that this is just a polymorphic serializer  behind the scenes.  And that means it's got all of the classic vulnerabilities  that polymorphic serializers have.  But let's explain a little bit  what I'm talking about there.  So .NET serialization vulnerabilities.  .NET serialization vulnerabilities  generally happen because you have a polymorphic serializer,  a serializer where the data is telling you  what type it wants to be.  So in this case, we've got a box,  it's some self-describing data.  It says it's a cat, it's labeled cat.  When your serializer sees that label,  it says, well, I guess I'm making a cat object.  And it just makes a cat object  and then sets some properties from the contents of that box.  And the problem with this is someone malicious  can come along and give you a box labeled pain.  Your serializer says, well, I guess I'm making some pain then  and you're having a bad time.  So if you want a little more information in general  on how .NET serialization works  as far as for those sorts of serialization exploits,  I suggest looking at the Friday the 13th Jason talks  from Black Hat 17.  But I'll also give you a few examples  of what this pain is here.  So in general, when I'm talking about pain here,  what I'm talking about is types that were,  if you tell an application to create them,  they're gonna have side effects  that can further exploit goals.  Either when you call their constructor,  set their properties, maybe the destructor  will do something that you want to have happen.  Here's a couple of classic ones.  Assembly installer has a path property.  When you set the path property,  it just calls load library on whatever path you give it.  So if you've been able to drop a malicious DLL  on a server somewhere,  you're going to be able to do DLL injection.  It turns out that if you give it an HTTP URL,  it will actually go and request the file from that URL.  It won't load it, but this is still really useful  for getting pingbacks  if you're attacking a server somewhere.  Object data provider is sort of the more classic  RCE gadget for .NET serialization.  It's got properties where if you set the properties on it,  you can call any static method on any type in .NET  with whatever string and integer parameters you want.  So people usually call process.start  just to pivot the shell injection.  Okay, so that's how .NET serialization vulnerabilities work.  Now I'll go back to LightDB  and explain what I'm calling  implicit serialization vulnerabilities.  So here's a remote code execution exploit for LightDB.  If you look at this JSON blob here,  this is going to be the JSON we're going to put into LightDB.  It's got that underscore type key  where it's telling you what type it wants to be.  It's going to be an object data provider.  That's that gadget that lets you call  any static method you want.  We're going to call process.start and launch calc.  And all we're going to do with this JSON  is convert it to bson  and then pass it into bsonMapper to deserialize it.  It's worth noting that  when you call the bsonMapper's deserialized method,  you tell it what type you expect and it does not matter.  So LightDB will actually respect  the type the data says it wants to be.  It'll go make it.  It'll set its properties.  Your serialization exploit gadget will run.  It will then try to do a cast that will fail  and probably throw an exception, but it doesn't matter.  Your code is already run.  Going back to how LightDB works.  If you remember, LightDB uses bsonMapper  to read its own storage.  So the problem here is that anything  that can put malicious data in the database file  can achieve RCE.  It's also worth noting that when a client's using LightDB,  they don't know they're using a serializer probably.  They're almost never going to call bsonMapper directly.  So this is an implicit serialization vulnerability.  The client is vulnerable to the serialization  that's in LightDB,  even though they're not using the serializer LightDB is.  And this makes that client vulnerable in a lot of ways.  First of all, LightDB, when it stores a database file,  it just stores a local file.  So a lot of applications use LightDB  just to write document formats or save files for games.  So if you provide someone a document or a file  that they're reading with LightDB,  you can put an RCE payload in there  and it'll run code when they open it.  LightDB is a NoSQL engine.  It also has queries,  which means you can achieve query injection  and then you can put a malicious record in the database.  And when someone reads that record, you've got RCE.  And there's one extra special exploit technique  I figured out for this that I'll come back to.  So what do you do when you find  a remote code execution vulnerability  in a major open source library?  Well, you look at all the other libraries that are like it  and find the same vulnerability there.  So here's essentially the same vulnerability in MongoDB.  So here's a JSON payload.  It's got this underscore T key.  That's the type specifier Mongo uses.  That's the way the data says what type it wants to be.  We're again making an object data provider.  We're going to again call process.start and launch calc.  And again, all we're going to do with this  is convert it into bson and then deserialize it  with the bson serializer that MongoDB uses.  Now it's worth noting that you also tell  the bson serializer what type you expect,  and that does matter.  So in MongoDB, it will actually check  that the type the data says it wants to be  is assignable to the type it's expecting to get  before it creates it.  So if you want to exploit MongoDB,  you have to find something in the data structure  the application's expecting that's open-ended  so you can fit a serialization gadget into it.  That said, it's almost always there.  When I've looked at applications that use databases,  there's almost always either an interface member  on something or just a member of type object  as like a catch-all.  And so you just put your serialization gadget  in that slot and you still have RCE.  Because MongoDB again uses this bson serializer  to read its own database,  it means that anything that puts malicious data  in the database gets your remote code execution.  MongoDB uses a client-server kind of architecture  most of the time.  So you can have one malicious client  that talks to the database, puts a bad record in there.  Some other client reads that you're running code  on that other client.  You can also do, again, query injection.  I will say that I was only able to exploit  the .NET driver for MongoDB, not Java or Python.  I won't say you can't,  just that I couldn't figure out how to do it.  And then we're gonna move on to yet another  remote code execution vulnerability  for yet another NoSQL engine.  This one is RavenDB.  So once again, we've got a JSON payload.  This one, the type it says it wants to be  is a Windows identity.  Windows identity is a JSON.NET RCE serialization gadget.  I suggest looking at YSO Serial  for details of how it works.  But essentially, it lets you pivot  to a binary formatter payload,  which you then use to get RCE.  And in this case, what we're gonna do with this payload  is we're just going to actually make a connection  to the database server and then do a put request  to stick the JSON in the database.  So RavenDB lets you interact with the database in two ways.  You can read or write JSON to it,  or you can read or write objects from it.  And so what you can do is if you put malicious JSON  in the database and it's read as an object,  that gets you RCE.  Now, it's worth noting here again  that the type that's being expected matters.  There's an assignability check like there was in MongoDB.  And so you have to actually have some way  to fit your payload into the expected types.  This, again, is an implicit serialization vulnerability  because RavenDB is just using JSON.NET  with unsafe settings to read its own storage.  So anything that puts bad data in the database gets you RCE.  And that special attack pattern that I mentioned  for LightDB works here also.  And I looked at some things that were NoSQL  but not strictly databases.  So here is a remote code execution vulnerability  for service.redis.  Service.redis is sort of a NoSQL wrapper for a Redis cache.  So here we've got some JSON.  It says what type it wants to be.  In this case, it's saying it's going to be  an assembly installer.  That's the one that lets you call load library  on an arbitrary path.  We're just going to say I dropped a malicious DLL  somewhere for it to read.  And then what we're going to do with this JSON  is we're going to stick it in the Redis cache  and then read it back.  So when we stick the JSON in the Redis cache as JSON,  it's just JSON, but when you read it back as an object  using service.redis, it's going to turn into  whatever object we say it wants to be and it can run code.  Now, again, the type matters.  So when you're using service.redis,  you tell it what type you're expecting  and the payload you're using has to fit  into the object draft you're going to have there.  This is, again, an implicit serialization vulnerability.  So because service.redis is using unsafe serializer  to read the Redis cache, anything that lets you  put bad data in the Redis cache also gets you RCE.  And that extra pattern I keep talking about  works here also.  And now I'm going to tell you a little bit  about how I discovered it.  And that's because I was looking at  one other NoSQL engine in .NET and that's MartinDB.  So MartinDB, like RavenDB, uses JSON.NET  with unsafe settings to read its own storage.  But unlike RavenDB, it doesn't just let you write JSON.  You can only read and write objects from the database.  And when I tried to write an object to MartinDB  that was just like a serialization exploit gadget,  it would choke on it every time I tried.  So I played with that a lot and I found  a completely different way to attack it.  And that's what I'm calling a serialization mutation attack.  So here's a remote code execution payload for MartinDB.  This one's a little bit different.  So what I'm going to do here is I'm going to make  in .NET a dictionary of string, string.  This could be a hash table too, but you need something  that's got key value pairs mapping a string to a string.  And what I'm going to put in that dictionary  is first a dollar type key paired  with the name of a .NET type.  In this case, Workflow Designer,  which is another JSON.NET serialization gadget.  It lets you do an arbitrary XAML read.  Again, look at YSO Serial for details about how it works.  And then I'm going to do one other thing  where I'm going to set another key value pair  where this is the name of a property on Workflow Designer,  which is the one you set the XAML with  to get an arbitrary XAML parse out of it.  And what I'm going to do with that  is I'm just going to write it to the database.  So if you write this object to the database  and then read it back, that will run code,  it will launch calc.  And that's kind of weird.  We're writing a dictionary to the database,  but when you read it back, it runs calc.  Why does that work?  So this is using JSON.NET as its serializer.  So let's look at how this works in JSON.NET.  So in JSON.NET,  if you serialize one of these dictionary string strings,  like say you have a dictionary  where you've got a key named fruit and the value pair,  it uses the key names exactly as you provide them.  So your key as fruit is just going to go  into the serialized JSON as the key named fruit.  Now, if you compare that  to what an RCE payload looks like for JSON.NET,  here's an example of one.  You've got that type specifier key,  that $type,  and then you've got a .NET type name  as a value for it and so on.  And the key trick with this  is there's nothing special about that $type key.  There's nothing special about the type specifier  used really in any of the serializers I've talked about.  So you can make a key for a string string dictionary  named $type,  and it turns out that if you serialize  one of those string string dictionaries in JSON.NET  or most of the other serializers I've talked about,  it just uses the key directly.  It doesn't filter it out  even though it matches its type specifier.  So what happens there  is that you're essentially colliding with the syntax  of what that RCE payload looked like.  You're making it just output data  where it's going to be the type specifier.  So when this object gets serialized and then deserialized,  it mutates into a different type entirely,  and you can choose whatever type you want.  And this doesn't just work for dictionary.  It works for hash table, J object, expand to object,  and like 50 others.  Just go look around the .NET  for things that have key value structures.  And because of this mutation attack,  you can do a lot of attacks on serialization  that usually weren't considered possible.  So say you have a website that takes some key value data,  and this is a screenshot from a certain website  you might recognize that did not have this vulnerability,  but does let you enter key value data  where you can choose both the keys and the values.  And you send that to a web front end with a form post,  and on the web front end,  they're going to make a dictionary or a hash table  with the data you sent them.  And later on, say that dictionary or hash table  gets serialized to a database or a cache,  and then later on after that,  it gets read back from that database or cache  using an unsafe serializer.  Well, in that case, you can provide key value data  where you're using that type specifier as the key name,  and when it gets read from that cache  on some back end server,  you can make it so it mutates into whatever object you want.  It's now your serialization exploit gadget.  It's now that pain.  And you've got real code execution whenever that happens.  So I was saying that was that extra attack pattern  against all of these NoSQL engines.  Here's how that works against LightDB.  So LightDB, you can make a dictionary string string.  You put your payload in there,  so you've got that underscore type key  specified with a type name,  in this case, assembly installer.  So we're going to do, again,  a arbitrary call to load library.  We're saying we're loading malicious DLL.  And all you do is you write it to the database  and read it back.  Now, this hack is kind of magic.  It doesn't matter where this is in the data structure.  If you can control two key value pairs  in some part of some object graph,  if it gets saved and read back, that gets you RCE.  And this actually makes a lot of attacks  really ridiculous and easy.  Like, there's some application that's just asking you  for a couple of string pairs,  and later you get RCE when it gets read from the database.  And this kind of attack works with a lot of serializers.  Here's a list of all the ones I know.  These are all the .NET serializers I know  where this sort of mutation attack works.  You'll notice these are all JSON and BSIN serializers.  This doesn't work for binary formatter  because it doesn't use anything like this kind of syntax.  And it's also worth noting that this doesn't work  against MongoDB's serializer.  You'll note that there's different requirements  for this to work in certain cases.  Some of them, you have to control the first key value pair.  Some of them, there's that assignability check.  Some of them, there's other like specific  unsafe properties you've got to set.  So there's a lot of variability  in how exploitable mutation can be.  For example, JSON.NET, like most popular  open source library in the world as far as I'm aware,  you can get mutation attacks against it,  but it's a little bit tricky.  You have to control the first key value pair  because that's the only one it'll read  the type specifier from.  It has to be deserialized using unsafe settings.  It has to be serialized in such a way  that it doesn't double up the type specifier.  And in general, I would suggest experimenting with this.  There's a lot of weird special cases and nuances,  but sometimes you can make this work  and you can use this to exploit things  where the serialization is just not something you can touch.  The serialization happens on the back end.  You can't see the deserialized data.  Maybe it even gets an HMAC stuck on it.  It doesn't matter.  On the other hand, there's serializers  where this just works all the time.  If you've got JavaScript serializer with a type resolver,  it will go out of its way to make the exploit work.  It doesn't matter if you've got other entries  in your key value storage.  It doesn't matter if your type specifier  is the last thing in the list.  It doesn't matter if the assignability doesn't make sense.  It'll just run the code and it'll just work.  You can also do kind of a blind scanning technique  to find these vulnerabilities.  If you've got websites out there  that you think are running on .NET  and might have some back end cache or database,  you can just stick key value data in there.  You can use that assembly installer pingback trick  I've talked about, and you can wait to see  if you later get a request back to your own server.  So you can stick data in services blind,  use maybe unique URLs for your pingback  so you can see which ones talk back to you,  and then maybe later on when it gets read from the cache,  you'll get a request and you know  there's an RCE happening there.  You can defend against these attacks in a bunch of ways.  If you're writing an application,  the best thing to do is don't use a polymorphic serializer.  And I'm gonna say that a lot in this talk.  Don't use a serializer where the data gets to tell you  what type it wants to be.  If you have to, for some reason,  you can try using a serialization binder,  but I'm about to tell you how to bypass serialization binders  so kind of grain of salt there.  So here's how to bypass serialization binders.  In general, if you're talking about using  a serialization binder for security purposes,  it's acting like a filter.  What's happening is during deserialization,  your binder's gonna get asked about every type  that's directly referenced in the serialized data,  and it'll say, okay, this is the type I expect, go ahead.  Or if you're doing it right, you throw an exception  when some type you don't expect shows up.  And that means if someone throws pain at you,  you say, I don't know what pain is,  you throw an exception and nothing bad happens.  So if you're doing it right,  your serialization binder looks sort of like this.  What this is is just an allow list  of all the expected types.  It's a string allow list for both the assembly name  and the type from the assembly name,  and if you see one that you don't expect,  you throw an exception.  The problem is a lot of times people don't do this.  Usually what you see for a serialization binder  is something more like this,  where you have some assembly you've written yourself.  You say, well, I trust all my types,  there's no crazy serialization gadgets in there,  so if the type says it's coming from my assembly,  I'll just allow it and I'll use type get type  to actually get the type out of there.  The problem with this approach is,  say your assembly contains a type like this.  This is an initialized list type we're going to invent  that just derives, inherits from the generic list type  in .NET, and we're adding another property to it.  That seems pretty harmless,  but if you've got a type like this  in that assembly that you're trusting,  you can exploit it like this.  So here's a JSON payload  to bypass that serialization binder I just showed you.  The type it's saying it wants to be is initialized list,  that type I just mentioned,  but the type in the template for that is assembly installer,  that one that lets you do an arbitrary load library.  The trick with this is,  initialized list is the type you're getting asked about,  that comes from your assembly,  so that binder is okay with it.  And you'll notice that assembly installer  is only ever referenced inside the template here,  but when this values part of the JSON blob gets deserialized,  it'll still make an assembly installer object,  it'll still set its path property,  and you're still doing load library,  so your RCE is still working.  There's a trick here  that when you serialize this with JSON.NET,  it'll put another dollar type entry in there  for the assembly installer,  but you don't need it.  It can figure out what it's supposed to be  if it's not there,  so you can just take it back out again  and then bypass the binder.  There's another trick you can use  to bypass serialization binders  that I'm calling contagion.  So for JSON.NET and a lot of other Beeson  and JSON serializers,  you've got that dollar type entry  that's saying what type it's supposed to be,  but that object you're creating  has members, properties, constructor arguments  that have their own types,  and you don't have to specify  the types of those in the JSON.  If you serialize it, it will,  but if you don't,  the serializer will just figure it out.  So if there's some serialization gadget you wanna use  and it's a member of something  that's a member of something  that's a member of something  that you can get past the binder,  you can use that one object  that has it in its tree somewhere  to get it past the binder.  Here's one example.  So Windows Identity that I mentioned before  is a JSON.NET RCE gadget.  It lets you pivot to binary formatter.  And you could have a serialization binder  that specifically block lists that.  And if you do that, you can still get it by.  The way you do that is you use  a Windows Authentication Event Args object.  So if you serialize Windows Authentication Event Args,  it has a constructor argument called Identity  whose type is Windows Identity.  So when you serialize that,  the only type going by the binder is this dollar type  because the only things that the binder gets asked about  are the types explicitly listed in the JSON.  But when the identity part of it gets deserialized here,  it'll still make a Windows Identity object.  It'll still set its properties.  You still get RCE.  So that's a lot of problems.  What if this has been fixed?  So I am with Microsoft.  I practice responsible disclosure.  I told all of these people about these issues  in January or earlier.  Everybody except MartinDB made some sort of fix.  MartinDB, as far as I've checked last, still hasn't.  MongoDB's fix is pretty solid.  I don't know how to bypass it.  They added a pretty strict allow list  on the types that can get created during deserialization.  It seems good.  Everybody else here added a block list.  LightDB also added an assignability check  so that puts them about on par for MongoDB  before they made a fix.  I just showed you how to bypass block lists.  I can bypass all of the fixes for LightDB,  RavenDB, and ServiceDoc.Redis.  Like I said, MartinDB didn't get fixed.  I told all of these people,  look, I can still bypass these fixes.  They said, we're not making additional fixes.  So there's remote code execution vulnerabilities  that are live right now for all of those libraries.  Worth looking at.  The mutation attack I mentioned against json.net  is not being fixed.  I talked to James Newton King,  the maintainer for json.net about this.  He said, essentially, it's supposed to do that.  So that behavior is not going to be changed.  If you've got some application that's using json.net,  it might be vulnerable to mutation.  Similarly, JavaScript Serializer,  the .NET Serializer I mentioned  that works really well for mutation attacks,  will not be fixed.  I talked to the .NET team about this.  They said, we tell people don't use JavaScript Serializer.  We tell people don't use TypeResolver.  So we're not gonna fix them.  Just don't use them.  So, best practices to avoid these issues.  First, thing I keep saying.  Don't use a polymorphic serializer.  Don't roll your own.  It's a really bad idea.  Don't have that data let you tell you  what type it wants to be.  It leads to all kind of problems.  Don't call type get type because if you're doing that,  you're probably writing a polymorphic serializer  even if you don't realize you're doing it.  Similarly, in Java, don't call class for name.  Also, remember that you can't use an unsafe serializer  anywhere because mutation attacks.  If it's on your backend, if you've got an HMAC,  it doesn't matter for mutation.  You can attack like deep copy tricks.  A lot of people use serializers to just deep copy objects.  You can get RCE out of that because of mutation,  which is kind of silly.  So, don't use unsafe serializers anywhere.  This one kind of hurts,  but maybe don't read untrusted data from NoSQL.  Mongo might be okay,  but it kind of looks like every other NoSQL engine  I've looked at.  You can get RCE if someone can write bad data  and you can read it back.  Now, I only really looked at .NET NoSQL engines,  but there's kind of a pattern here with NoSQL  where they say, just take this object.  And then later on, you can tell the NoSQL engine,  I want the object back and I don't care what it is.  Anytime you have that pattern,  there's a polymorphic serializer in there somewhere  and you can probably get RCE out of it  if you want a research project  or want to go find libraries that are vulnerable.  Maybe you look at Java or Python NoSQL engines.  Don't try to use serialization binders.  It's possible to write a good one, but nobody ever does it.  Everybody screws this up.  I see bypasses for these all the time.  In general, you're better off architecting your application  so you don't need a serialization binder in the first place.  And now I'm going to get into the bonus stuff  that's just for DEF CON.  So, I've been talking about .NET framework exploits,  but what about .NET 6 plus?  Everyone seems to think that's different.  It's not going to have these serialization vulnerabilities.  So, since 2016, .NET has had a couple of different flavors.  There's .NET framework and then there's .NET.  That's what they want me to call it,  but .NET 6 through 8.  Those are the ones people use right now.  All these exploits have been .NET framework exploits,  so the ones that are in YSER serial.  But what about .NET 6 plus?  Can you do this sort of stuff there?  There is this myth that .NET 6 plus  is immune to serialization attacks.  So, here's the CVE mongo opened  for the vulnerability I found.  And it's kind of an eye chart there,  but I'll underline the important part here.  And what they said was it must be running Windows host  using full .NET framework, not .NET core.  That's not true.  Similarly, if you look at YSER serial,  they have a bug there,  which is, is there any gadget for .NET core?  And no one has found one there.  So, admittedly, exploiting .NET 6 plus is harder.  A lot of the exploitable types,  the gadgets that people use in .NET framework  just aren't there in the framework at all.  There's also this whole issue where .NET,  .NET 6 plus, whatever we're calling it,  actually divides the framework into three parts.  There's .NET core, there's ASP.NET,  and there's the Windows desktop part.  And depending on how you build your application,  you only get some of the DLLs that are even visible at all.  So, you can only use gadgets from the ones  that are appropriate to how you build your application.  So, the ASP.NET core app types  and the Windows desktop app types  won't be found by type get type.  You can't deserialize them unless you've built  with an ASP.NET app or a Windows desktop app.  But you can still do deserialization exploits.  So, object data provider is still there in .NET 6.  It's still there in .NET 8.  You have to have Windows desktop loaded for it to work,  but if it's loaded, the payloads I've been showing you  for object data provider, they just work fine.  There are also some deserialization gadgets  that do exist in .NET core app.  And now I'm going to go to the parts  that aren't on my slides  because I think I've got some time left.  So, I told you earlier how you can get a ping back  with assembly installer.  There's a similar trick you can do in .NET 6,  in .NET 8, and so on.  And there's a few types you can use to do that.  One of them is assembly dependency resolver.  Another one is system.io.fileinfo.  The trick with both of those is they will call create file  whatever string you give them.  So, assembly dependency resolver  has a constructor argument, which is just a path,  and it'll just call create file on that path.  The file info type, you can set the read-only flag  on a file with it, and you can do that, however.  So, you can also use that as a payload to do DOS  because you can make files on the server read-only.  But when you do that,  it'll also call create file on that path.  Now, there's a thing with create file in Windows  where if you give it an internet SMB URL or a WebDAV URL,  it'll go talk to that.  It's happy to do it.  So, if you've got an SMB server on the internet  or a WebDAV server somewhere,  you can use those gadgets to get a ping back to that server.  Now, a lot of times,  if they're doing their opsec correctly,  S and B outbound will be blocked  on the server you're trying to attack.  And sometimes the WebDAV redirector  won't exist in the Windows install.  So, it's a little bit iffy,  but in my experience,  usually one or the other of those works.  So, you can still get a ping back, essentially,  by using assembly dependency resolver or file info,  setting the read-only flag,  and then giving either an internet SMB URL or a WebDAV URL.  And that's actually all I had.  So, are there any questions?  Oh.  Thank you, thanks.  I saw one over here.  Sorry, can you tell me that one more time?  Sorry.  Okay, the question was,  do I have any examples of the vulnerable games?  I don't remember which ones they are,  but what you can do is go on,  GitHub or, like, if you go on to NuGet, okay, so two approaches. Go to NuGet, look at our  projects that are dependent on LightDB, and then look at where those get used, or just  search on GitHub for uses of LightDB for things that look like games. That's how I found a  bunch of our examples of that before. Yes, over here.  Sorry. You said that after you're reading the object, it will actually initialize the  object injection, right? So how did you find that in the first time? Because it's not something  that you typically think about when you start this research.  Okay, to clarify, was the question, how did I realize that the vulnerability was there  in the code that I was looking at to begin with?  Yeah, because you said, I can control the key, I can control the value, and then when  I read it, it will initialize the object injection, right?  Oh, okay. So as far as that goes, if you're looking for polymorphic serializers where  people are rolling their own, which is a really bad idea in general, what I look for when  I'm doing these sorts of code reviews is calls to type get type that are just being passed  a string, especially if the string somehow comes from user data. Type get type being  called on a user-provided string almost always is either unsafe serialization or someone  doing really sketchy with reflection and evokes. And both of those are probably RCE.  Does that explain it?  Yes, it is. Thank you.  Okay, in the middle here?  Okay, the question was, did I look at the AWS? I did at least, okay, the question was,  did I look at DynamoDB NoSQL? I glanced at it. I did not do an in‑depth test. It did  not have as easy of an exploit as the other ones I looked at. I won't say it's safe. And  then there was one over here.  Okay, the question here was the assembly installer exploit that I'm loading malicious DLL with  and how can I make sure the malicious DLL is there present on the system? In that case,  the assumption is you've got some other exploit that lets you do a file drop. Something I  should explain is the cases where I was using assembly installer exploits, that's because  the string is shorter than the object data provider ones. Object data provider works  for all of these too. So do lots of other .NET gadgets. Assembly installer I feel like  honestly is more useful for doing a ping back to an HTTP URL because that lets you do that  blind scanning I mentioned.  And one way in the back. You might have to come forward for me to hear you.  So the question was whether automapper and fast mapper that also use that sort of reflection  under the covers are also vulnerable. I'll admit I haven't looked at those. I'm honestly  not quite sure what you're referring to. So maybe we can talk a little bit more about  it after this. And if there's no other questions, I'll finish there. Thank you.  If there's no other questions, I'll finish there. Thank you.


url: https://www.youtube.com/watch?v=Bq7Z3X4xwCE
title: DEF CON 31 - Runtime Riddles - Abusing Manipulation Points in the Android Source - Laurie Kirk
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=Bq7Z3X4xwCE",
    "title": "DEF CON 31 - Runtime Riddles - Abusing Manipulation Points in the Android Source - Laurie Kirk",
    "description": "Android malware creators constantly struggle to devise innovative methods to obscure apps and impede reverse engineering. As numerous standard techniques have lost efficacy, I'll unveil the next frontier in Android obfuscation: runtime manipulation. Runtime manipulation alters standard application flow-of-control to bypass decompilers and emulators.\n\nIn this talk, I'll reveal my strategy for pinpointing manipulation targets in Android's source code. I will describe how I craft manipulators in native C++ once a suitable target has been located. This is accomplished by hooking Java methods via the Java Native Interface (JNI) and typecasting the handle to a C-style pointer. Runtime manipulation can entirely remove traces of ClassLoader calls which are unavoidable for standard Dalvik Executable (DEX) packing, but are also easily discovered and hooked. This technique also effectively breaks cross-reference calculations within all Android decompilers.\n\nI will demonstrate and equip attendees with a custom Android library for devices running Android 13, providing a new tool that enables runtime manipulation experimentation. In addition, I'll demonstrate my methodology for pinpointing Java targets and modifying their underlying native data structures.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2519,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   She's going to give you a presentation about riddles.  Well, close enough. I'm talking about run time riddles. And I'm also standing on a  platform so I hope everybody is able to see me and I hope I don't fall off. But today I'm  going to be talking to you about abusing manipulation points in the Android 13 run time  for anti reverse engineering. So who am I? I'm Lori Kirk. I'm a reverse engineer at  Microsoft. I specialize in cross platform malware analysis with a focus on mobile threats. I  also run a YouTube channel under my alias Lori Wired and I'm also on GitHub and Twitter if  you want to connect with me. And today I will be representing myself as a security  researcher, not representing Microsoft. And if you'd like to follow along with this  presentation at all, feel free to go ahead and scan the sketchy QR code right there. I  promise it's not malicious. But I've also added the URL to my presentation if you don't  want to trust me, which is fine. So let's get right into it. Now imagine you're a seasoned  security analyst. And you're analyzing an Android application. And you've checked every  single method inside of this application and it's all looking clean and you're not finding  any malicious indicators inside of this application. So you're about to call it and say  that this application is indeed clean. And then you get to this part of the code. And you  might think this looks entirely benign. We have a log.e method which is an official  method inside of the Android framework used to log an error to the console. And it looks  like it's setting a button to the Android application screen that the user can interact  with. And you might think this code is perfectly safe. This code has actually been  dynamically modified and hooked during run time of the application so that every time the  official log.e method inside of the Android framework is invoked, it's actually  executing an underlying info stealer inside of custom code. So this actually just stole  your data. Which brings me into my agenda for today. We're going to manipulate the Android  13 run time. We're actually going to replace the official Android APIs while our  application is executing to execute our own custom code. This also works on Android 14  in the upside down cake release, the beta version. And I'm also going to provide a new open  source tool to the community that I just released about an hour ago. And this is going to  let you import this as a library into your own Android applications to provide additional  obfuscation for your Android APKs. And this will work for any device that you're trying to  protect your Android applications against. And it's specifically designed before Android  13 and 14. Now for a little bit of background before we really get into it. So the  primary goals for obfuscation inside of Android for dynamic obfuscation is to load  additional code into the Android run time. So basically this is trying to defeat static  analysis of Android applications. Basically there's an additional class or method or  even executable that is defined on disk that Android malicious or benign developers will  try to include inside of their Android applications to prevent static analysis of their  code on disk. So if they load and execute this code while the application is actually  running and a reverse engineer is taking a look at this code, they actually won't know  unless they dynamically analyze their code that this additional code is actually  executing. So there's a few methods that are really commonly used for dynamic code loading.  These can be found inside of the Android framework. You might see DEX class loader, path  class loader or even some different Java reflective calls. And basically they will take an  additional Dalvik executable on disk and load that into the Android run time or they can  even work on different methods, classes or variables. So these are all effective at  actually altering the dynamic flow of the application. The only problem is, is that  these are really easy, easily searchable inside of the code. So I took a malicious  application and I threw this into my favorite Android decompiler JDEX and all I need to  do is go search text and then start typing in my favorite Android APIs and I can find all  of these dynamic code loading calls in plain text. So this is really simple and at that  point I'm able to fully understand what this is doing and be able to potentially analyze  those additional code loading calls. Furthermore, there's a lot of default frameworks  inside of Android. You might be familiar with Frida that's actually able to hook methods  for a lot of different platforms, not just Android while the application is running. Or  there are hooking frameworks that are designed specifically for Android applications. A  popular one might be Medusa which actually by default hooks a lot of these different  Android APIs that are specifically targeted for code loading and will dump the executable  for you so that you can take a look really easily and actually statically analyze that  additional binary. So when I started working on this presentation, I wanted to think, is  there a way that I could actually bypass these common API calls so I could try to hide  the dynamic modification of my Android application? Which brings me into my first point,  which is going to be manipulating the Android runtime directly. First of all, a little  background if you're not familiar. The Android runtime or also known as ART is responsible  for taking in binaries that are defined on disk. So these are going to be your Android  applications, your APK files. And actually parsing out all of the code from inside of  those, bringing those into the actual Android runtime environment, mapping those into memory,  making the relevant portions executable and actually executing the entry point of the  particular executable binary. So basically you have your Android runtime responsible for  taking your code on disk and bringing it into the runtime environment and importing any  necessary data inside of your application. The high level of it looks like this. You have  your method defined on disk. And then you have ART which is going to parse out all of that  data that I mentioned, bring that inside of our process memory and actually execute those  underlying instructions. So from here I had an idea. What if I could actually modify those  methods that have already been mapped inside of memory or even modify an entire executable  that has already been brought into the runtime environment instead of actually just messing  with it on disk? This means that we would avoid any of those plain text API calls that I  mentioned earlier, that DEX class loader, path class loader or in memory DEX class loader  that are so commonly used and such common targets for Android reverse engineers already. This  would also mean that we would not have any standard methods to hook with a lot of those  default Android frameworks that will commonly just dump the dynamic binaries that we're  trying to execute and hide. Now the only problem with this is that Android has a lot of  abstraction layers that we have to keep in mind if we're trying to actually hook and modify  these methods. So it's not just as easy as hooking the Java method, altering the behavior and  just having the execution. If we're actually trying to swap out entire methods or entire  executables and fields inside of our memory of our application, we actually need to modify  the underlying native structure of those Android methods. Now what you might be familiar  with is that the Android framework is actually written in Java. So this means that Android  developers write in Java or Kotlin and they'll import those Java defined official APIs into  their code. So the developer is only interfacing with the Java portion of these APIs. But what  you might not be familiar with is that the underlying implementation is actually defined in  native C++ code. So the Java basically works as a wrapper around a lot of underlying C++  implementation. The same thing goes for the official Android APIs as well as in our own user  binaries. We often have Java invoking the native C++ which actually contains a lot of the  implementation. The high level view looks something like this. You have your developer on  top interfacing with the Java portion of our application. And then we have this special  thing called the Java native interface or JNI that actually lets the developer and the  Java code communicate with the C++ code underneath and vice versa. So if you're trying to  think of the JNI, this is important so we're going to use it later. Think of it as the  bridge between our managed Java code and our native C++ code. And remember, we want to  modify the underlying C++ in our process memory instead of just looking at the Java  portion of this. So we're going to use the JNI to do that. This means that our new  methodology is going to be something like this. We're going to locate our Java target on  top. We're going to intercept those specific targets using that Java native interface  bridge between managed code and native code. And then we're actually going to dereference a  pointer that we're able to get with the JNI to modify and overwrite that underlying native  data inside of our process memory. So let's get on to our first point. We're going to talk  about finding entry points and targets within the Android source code inside of the  Android framework. This means that I'm going to first dive into the actual source code of  the Android framework. One thing that I really like about Android is that it's all  available for you online. You can read any of the source code. There's even really helpful  developer comments inside a lot of the code for you to understand. So we're going to look  into that top point right there and take a look at the Android platform and see if  there's any Java methods of interest that we could potentially use to actually swap  different relevant data inside of our application. Now the first target I looked at was  trying to swap an entire dex file. A dex file is a executable file and it contains all of  the actual Java byte code or executable code that's inside of your application that's  actually going to be run on the underlying processor. And if you take a look inside of  the Android framework, we have this dex file dot Java class that's defined that we're  able to locate. And this contains all of the relevant data for a dex file or Dalvik  executable file that's being mapped from disk into memory. Specifically if you look at  that M cookie field there on the left-hand side, this is containing a reference to that open  Dalvik executable file. So my first target was what if we took that M cookie field and  we actually swapped that with another field during execution so that we're executing an  entirely separate executable than what we would expect and what a reverse engineer or  anybody taking a look at our code would expect. But this didn't work super well for a  few different reasons. The main problem is kind of a chicken and egg scenario. So your  main Dalvik executable file is already initially kicked off as soon as ART gets the  input from the user to actually run this application, it's going to immediately call that  dex file that's already been mapped into memory. Now, how would you actually invoke your  code that's going to do the hook and swap if that main dex file hasn't already been mapped  inside? And if you're trying to map an additional dex file into memory, you have to use  those pesky API calls like dex class loader or path class loader that we were trying to  avoid that are so commonly hooked or else what's the point of doing any of this? So this  does not really seem like a viable option for us. So I moved on to trying to modify  individual members inside of a dex file. Specifically I found a very interesting portion of  code inside of the Android platform. So Android is actually built on top of Java and you  can see a lot of the original Java definitions and references are defined inside of our  platform. This is a field object. So every single field inside of an Android application is  going to be instantiated and get its own version of this when the application is actually  running. And this contains all of the relevant run time data for every single field inside  of an Android application. You can see we have our access flags, declaring class, and all  of the different run time data that we're actually going to need to use this field. So if  we keep on looking around here and try to find an interesting place to actually modify and  manipulate, I found this executable dot Java file and this actually contains an ART  method variable inside of it which is sounding really interesting. And if you take a  closer look at the ART method variable that I have highlighted right here from our  Android source code, this is going to contain the actual ART method structure for every  single method that is defined inside of an Android executable file. So every method  that's defined on disk gets a corresponding instantiation inside of the run time as defined  by this ART method structure in native code. So I have an idea here. How about we take  this ART method field and we try and swap two methods while the application is actually  running. So that's going to be my plan. We're going to have two methods and we're going to  try and overwrite one behavior with the behavior of another method to see if we can  actually do some manipulation. So I have my benign method, my fake malicious method, and  as soon as the application starts running, we're going to hook both instantiations of these  methods and try to overwrite that ART method field so that we can see if we can get  benign method to be called but malicious method code actually executed. So now we need to  move on to intercepting methods via the Java native interface. Remember that was that  really important bridge between native code and managed code. So what we need to do is we  actually need to call the JNI from our own native application in Android. We need to use  that to retrieve a reference or handle to both of those objects. And then we actually need  to load the corresponding ART method field for both of those. And then once we've  actually done that, we can do our overwriting. And this is going to be the code that's  actually going to be able to perform that. On the top there, you can see we're trying to  find the executable class that was defined inside of our Android platform. And then from  there, we're able to find that ART method field that is inside of that class defined in our  Android platform. And we also need to get this for malicious method and benign method so  that we actually have the instantiations of both of these since every single method is  going to get its own. Now there's one problem you probably didn't notice or maybe you did.  That ART method field is actually private. So this means that only instances of that  executable class or its children can actually access this ART method field which is kind  of a problem because we're trying to access that from code that has nothing to do with the  Android platform. We're just using it inside of our own user code. So this actually is a  really big problem because the ART method object is completely hidden from us. Or is it?  So actually the Java native interface does not respect access modifiers. So if we just  ignore the warning like any good hacker would, we can just run this code and it's going to  run and execute this just fine even though Android studio is telling me that this is wrong  and I should not be doing this. That's okay because it still runs. So now the first thing  that I wanted to do is I wanted to do something kind of simple. I basically just took the  handles to both of those objects that we were targeting and just set benign method equal  to malicious method and let's just see if it's actually going to work. So let's go to test  time. So I'm going to pull up my first video here. And let's take a look at this code  actually running. And if you're able to see here, I have two methods defined inside of my  Android application. I have benign method which is going to return the string I am benign. I  have malicious method which is going to return the string LOL. And we're just printing the  return value of benign method to the Android screen inside of our Android application. Now  this is my native code that we saw a little bit earlier. We're getting that executable class  with the respective ART method field. We're getting the objects for both of those benign  and malicious methods. And then if you can see highlighted there, we're doing something  really silly. Just setting benign method equal to malicious method. But hopefully this  actually works. And if it does, we're going to see LOL printed to the Android application  instead of the text I am benign. So let's actually let that run and see if this is going to  work. So real quick, show of hands who thinks this is going to work? Show of hands who  thinks this isn't going to work? Show of hands. Anybody asleep? Drunk? I don't know. Okay.  That didn't work. That's too bad. So let's go back to our slides. And we finished our actual  test which was kind of a dumb test just setting one value equal to another. We didn't  actually do any effort to understand what was happening underneath. So all that means is we  just need to dive deeper and we need to actually understand that underlying native  structure inside of our Android application, inside of our Android framework. So let's go  through and let's understand that native structure. First of all, if we kept on going and  we started spending a lot of time or too much time inside of the Android source code, then we  would find out that that ART method field is actually a pointer to an underlying native  ART method structure. So this ART method actually defines the whole representation for a  native ART method object that's mapped into process memory. So this is the native  representation of an ART method inside of our Android runtime. And we can actually find the  declaration of this which is put inside of ART method dot H. And this contains all of the  relevant data for any method that's going to be running inside of our Android application.  It's going to contain the access modifiers, the actual executable code or any data that is  needed for this method to fully execute and run. And if we keep on going, we can find the  individual fields defined inside of this ART method dot H. And one field of interest, if you  take a look, you can see entry point from quick compiled code. And as I said, really  helpfully, the Android source code provides a ton of comments defining what it's actually  doing. So we can figure out exactly what this variable stands for and what it is actually  doing. And this is going to be the actual native instructions compiled from this method  that are going to run directly on your underlying processor. So that sounds really  interesting. What if we actually change the instructions that are pointed to by this  entry point from quick compiled code? And I kept causing repeated crashes. So what I was  doing is I was working in a 64 bit operating system. So I just tried to take 8 byte  increments and actually just keep overriding those bytes bit by bit and seeing if I could  find where that entry point from quick compiled code actually lived inside of the process  memory since we had a handle to the beginning of that ART method field. But we don't  actually know where everything else is inside of that ART method field in memory. So my  new plan was, okay, I'm going to test every two bytes, keep going forward and forward  and forward with 8 byte increments and actually see if I could accidentally overwrite this  pointer in memory and then cause the malicious method to actually execute. But that was  totally not working and it was getting really frustrating because I was like, I don't  even know if I'm doing the right thing. I don't even know if I'm starting out correctly  right here because what if it's actually not the native structure? What if I'm looking  at something completely different and wrong? So I eventually just gave up on that. And  then I had a new bright idea. I thought, okay, I'm just going to take 64 random bytes  from malicious method and overwrite those with 64 bytes of benign method because I'm  working in a 64 bit operating system and there were like roughly 8 variables inside of  my ART method class. So I was trying to account for those sizes roughly. You can shout  it out if you disagree and think it should be another side. But we went with 64 bytes  here. So let's go to a second test and let's actually see if this is going to work.  All right. So this should look familiar for you. We have our executable class that we're  trying to get a reference to. We found our respective ART method field. We have our  malicious and benign method. And then we have that nice pretty silly line there of mem  copy, completely unsafe. Let's just copy over 64 bytes from malicious method to benign  method. And let's see if that's going to work. Okay. So let's see if that's going to work.  So what we want to see is LOL written to the screen instead of I am benign. So show of  hands now, who thinks that this is going to work? Who thinks that this isn't going to  work? Okay. I think that's the majority right now. Well, let's see. So I'm going to start  my application. Here we go. And it worked. So I'm going to go ahead and run my application.  So I appreciate the vote of confidence from everybody who thought it wasn't going to work,  but it did. So I kept on going after I figured out that it was that easy and you could just  make it work. And I wanted to see what are the actual specifications and what can we do  with this? So after a lot of testing and a lot of breaking stuff, I found out that the  methods have to have the same signature, meaning they have to have the same parameters and  they have to return the same type. They must be static. They can be declared in separate  classes or wherever you want inside of your Android application. They can have completely  different functionality. And they will work inside of the application context, meaning  that if you're in your app, you actually can't modify the methods of another app, but you  can do whatever you want inside of your own application, which is good enough for us and  for obfuscation. So that's cool. And overriding random 64 bytes in memory does work, but  let's actually try to increase our accuracy a little bit. So I'm going to do some byte  math now and we're going to calculate all of the different offsets for this ART method  object and see where everything actually is in the process memory of our application. So  the Android source code, I was taking a look at it and it itself is actually finding these  offsets in memory using the actual size of the variables defined in our ART method dot  H that defined all of our method components. So this is actually used by the Android, the  official Android run time for getting and setting these values. So I thought I could  either count the sizes of all of these different variables inside of here or I could let it  calculate itself, which is exactly what I did. So I created a dummy ART method class. I  stole all of the source code that I thought was relevant for the ART method class, put it  in my own application and just added the necessary member variables for that. And then I  let the program calculate itself and print its own offsets to all of those in memory.  And this is what it looked like. It worked really well. I found the corresponding  variables defined inside of our ART method dot H and I wrote those down so that it would  print out the offsets for every single one based off of the defined sizes that the  actual application, that dummy application that I was running actually found. So those are  all of the correct offsets in memory for every single variable that's defined inside of  our native C++ ART method structure. So now it's time for a little bit of byte math. If we  keep going and use those actual offsets that we found, we can take the actual bytes for two  objects or two methods that we were trying to calculate in memory and associate those  particular bytes with their actual variables and types. And we can see we have our  declaring class, our access flags, that really important entry point from quick  compiled code there on the bottom right hand side. And I was working in a 64 bit  architecture so those are 8 bytes long because those are actually pointers to different  locations in memory that are actually defining the implementation and data for our ART  method object. So now that looks cool but I wanted to know did it actually work? Are  these offsets correct? Because I'm saying they are and it looks kind of okay but did it  actually define the specific locations in memory and do those bytes point to anything? So I  wanted to look specifically at that entry point from quick compiled code because this should  just be arbitrary native code that's going to execute on your underlying processor. So this  is actually going to be assembly instructions if you disassemble them. And I look at it, I  mean that looks like disassembly to me, looks like a function prolog that's going to be  setting up the actual code for our Android method. And we have all of that, all of those  relevant native instructions that are going to be setting up this native method. So I  think that worked and I think we actually have our correct offsets and we know exactly  where everything stands in memory and we can override it if we wish. Now we have the  exact sizes that we need to do if we're trying to overwrite an entire method or affect any  of the individual variables inside of that method. And if you want you can look closely. I  have all the sizes written there but I won't go into the details too much. Feel free to do  that byte math on your own. And additionally you'll have to account for if you're running in  a 32 bit or 64 bit operating system but you should still have the same offsets for ARM or  x86. So our calculations are actually complete at this point and now we have successfully  finished our byte math and we fully understand the native and Java structure of our ART  method objects. And we can pretty much do whatever we want from here. So I thought okay,  let's have some fun. How far can we push this and what can we do with this? So I had  another bright idea. What if we took all of the official Android APIs and we tried to  replace them with our own custom code so that the developer or a reverse engineer is going  to think that we're calling those official Android APIs but we're actually executing  something entirely different. So my target now was the official log dot E method which  again is just logging a string error to the console. If you look at it in the Android log  cat you're able to see these messages. And this is used by many different Android  applications both malicious and benign. It's a very common method. Reverse engineers  will pretty much completely gloss over this method if they actually see it because it's  entirely benign. So what if we took this benign log dot E method and we actually had it  steal all of the data on the device and replaced the log dot E functionality with a  malicious info stealer. So what we would have to do is I had to create a static method  that had a matching signature. So remember it's going to have to have the same parameters  and return value but the actual implementation can be entirely different. So this is going  to contain the code that's actually going to get executed every time that log dot E  official Android framework method is invoked. So it's going to invoke my code instead of  theirs. So let's do a test and let's see if that's actually successful and see if it will  work. So I'm going to open up my video inside of here. Looks like it's already running.  And this should start looking familiar to you. We have the Java native interface which  is hooking both instances. One is going to be the instance of the log dot E method and  then one is going to be the instance of our new custom method that's actually going to  get executed and then we're going to overwrite 32 bytes in memory since we upgraded from  our random 64 bytes to actually account for the correct size so that we can actually  completely overwrite this and execute our custom code. So now I'm going to be running  this and I'm going to pull up my application and I'm actually invoking that log dot E  method repeatedly. So every time that log dot E method is invoked, it's then going to  sleep for two seconds and instead it's going to be executing our fake info stealing  functionality. And on the right hand side, after it's sleeping for two seconds, you can  see it's going found installed application, found installed application, enumerating  through all of the applications in your device to actually steal that data from those. Even  though this has actually never been invoked if you take a look at the method on the device  statically. So let's go back to our slides. So now it's your turn to try your hand at  manipulating the Android run time. I just released an open source tool about an hour ago. This is  called Artful and it's built for manipulating the Android 13 run time but I did just do a  check on Android 14 upside down cake and it was perfectly successful at manipulating that  as well. This should work on many different API versions of Android although I have just  tested on the latest versions since those were my primary targets. So what is this? This  is a library that you can include inside of your Android applications for dynamically  swapping the behavior of methods from those that you would expect on disk. So it's doing  all of the complicated calculations on the back end so that you don't have to worry about  calling the Java native interface directly or actually doing the calculations of those  underlying bytes and native code. This works for your user methods. I have default  methods that will take either an object or the signature of two methods that are defined  inside of your application and you simply call the Artful library that you very easily  included into your app and then you can swap the behavior of any of those two methods.  Additionally I have some default Android framework official APIs that this will replace and  you can call those and simply pass in the object that you would like that has your new  custom code that's going to actually be run every time that Android framework method is  called or you can call the first method and actually swap out different Android APIs if  those are not implemented. Additionally I included the dummy ART method class that's  defined inside of the Android source code so that you could print those offsets if you  wanted to do additional calculations and if you want to actually try this and extend it to  support a different API version, all you need to do is take those variables that are  defined inside of the ART method object of the specific API that you're trying to  support and it will calculate the updated offsets for you. So let's go through and let's  summarize some of our results. Primarily the main challenges for this are understanding  the code inside of the Android open source project. It might be open source but there's a  lot of overhead that you need to understand to be able to actually follow the flow of  control inside of the Android source code. You need to be able to follow from Java land  over to native C++ land and understand where you're going. Additionally you need to be  able to know which Java target you have and be able to calculate the sizes of the  underlying C++ objects that you're trying to manipulate. Also you have to do that  complicated pointer math if you're trying to find the offset to a particular variable  inside of the Android source code and you also have to account for the differences in  Android versions since with every single code change inside of every single Android API  release or update, these calculations could be entirely different if they added additional  functionality or if they removed different variables from the source code. Now the  benefits of this, if you're able to do that, is you're going to be able to avoid all of  those standard class loader API calls from inside of your code and you're going to be  able to completely avoid that dex class loader, path class loader or any of those Java  reflective calls. This means that you're going to be able to execute unexpected code while  the application is running. So if you have your two methods in memory, you're going to be  able to define your entire custom code and if a reverse engineer is taking a look at your  application on disk, they won't realize that your actual target method is being invoked and  they'll only see invocations of the benign methods that appear on disk. So this effectively  thwarts a lot of different reverse engineering and any static analysis of your binary so  that you can further obfuscate and protect your applications without use of the standard  API calls. So here's an example of an application that I created using my artful library and I  had one call that's going to replace a benign method with a new method that had custom  behavior inside of it. And I threw this again into my favorite Android decompiler,  jdex, and I just hit the cross references button and there's actually no references to this  method. So if a reverse engineer is taking a look top down from the application, they  might entirely avoid actually looking at this method and never see that it's referenced and  see that it's completely hidden. Additionally, this has no calls to those standard class  loaders for dex class loader or path class loader or the standard Java reflective calls. So  that means if you remember those frameworks that automatically hook a lot of relevant  methods that reverse engineers will try to use to dump the dynamic code that's getting  executed on the system, all of those checks are going to actually fail and they're not going  to be able to find these methods that are getting invoked. Now they could try to hook the  different Java native interface calls that are actually doing the manipulation of these  methods, but those JNI calls actually look entirely benign since a lot of applications will  use the Java native interface to communicate back and forth between their managed Java  code and their native C++ code. So how would anybody know that this is actually an  obfuscation technique? Now go modify the Android runtime and you should be able to solve  this. So thank you so much, everyone. So I do have time for questions if anybody wants to  ask them. Otherwise I'll step down up front if you would like to ask me directly. And this  again is another sketchy QR code but it links to the artful tool that I was talking about. So  if you're feeling brave, go ahead and scan it. Yes.  So the question was, if you're having reflective calls inside of Java code and you're  having reflective calls inside of native code, how does this benefit if you're having those  reflective calls inside of native code instead? So the way that a lot of the hooking  frameworks actually work is they'll hook these API calls no matter what if they're invoked  from Java code or native code. It actually doesn't matter. So if you're using these JNI  calls, yes, they could be hooked and analyzed by a reverse engineer. But there's nothing to  say that they'll know exactly what's happening. They'll probably just be very confused and  not realize that this is doing anything interesting since it's actually not commonly used  as a dynamic code loading thing. It's basically just hooking the actual ART method object.  So there's not any dynamic code loading happening since this method has already been loaded  into the run time. So it basically just looks benign. Any other questions? All right. Thanks  everybody.


url: https://www.youtube.com/watch?v=ZB60UDJPj4Q
title: DEF CON 31 - Route to bugs - Analyzing the Security of BGP Message Parsing - dos Santos, Guiot
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=ZB60UDJPj4Q",
    "title": "DEF CON 31 - Route to bugs  - Analyzing the Security of BGP Message Parsing - dos Santos,  Guiot",
    "description": "This talk discusses an overlooked aspect of Border Gateway Protocol (BGP) security: vulnerabilities in how its implementations parse BGP messages. Software implementing BGP is relied upon for Internet routing and for functions such as internal routing in large data centers. A lot of (deserved) attention is given to aspects of BGP protocol security discussed in RFC4272, which can be mitigated with the use of RPKI and BGPsec. However, recent BGP incidents show that it might take only a malformed packet to cause a large disruption. We will present a quantitative analysis of previous vulnerabilities in both open and closed-source popular BGP implementations and focus the talk on a new analysis of seven modern implementations.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2724,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   When you exit, please exit out the back right side.  Actually, if you're looking at me, it's your back left side.  My right side.  Good body girl, way your body look tight, and me and you up inside this dance here tonight.  Me no see you with no partner, who upset me right, she say no, but she still say you're forward and bright.  Let we go inna the corner, out of the life force make me, buy you a drink babes if that's alright.  Me ask her what she want, she say brandy and Sprite, so why you want a double, she say yeah if you like.  Come back with the drinks, then me grab she by the hand, take her now and darken her for your slow wine section.  The way she hold me, me feel the connection, me know she feel me cause she ask me a question.  Somethings where she a tell me lordy, turn me on, and when she say she would, I love her starring upon.  Me leg then buckle, me head it gone, me long love it and me, yeah when me ready fi prop up.  You never, never, never, never cross over. You never, never, never, never go cross over.  You never, never, never, never, cross over You never, never, never, never, go promise  You never, never, never, never, cross over You never, never, never, never, go promise  You never, never, never, never, cross over You never, never, never, never, cross over  Music  Music  Nonstop  Music  Nonstop  Music  Music  Nonstop  Music  Nonstop  Music  Music  Nonstop  Music  Nonstop  Music  Nonstop  Music  Nonstop  Music  Nonstop  Music  Nonstop  Music  Nonstop  Music  All right, if you're coming in, come to the front.  These guys are lonely and sad.  Well, lonely at least.  They look happy.  You guys happy?  Yeah, they're not sad.  Are you sad?  Yeah.  Okay.  Anything I can do to help?  Okay.  Okay.  All right.  All right.  So I'll let you guys get started.  I want to give you a whole 45 minutes.  So one of us will be down there.  We'll give you a handshake.  Fix this always.  And then we'll be done.  And I'm going to interrupt you in about five minutes for shopping.  Okay.  I've got a wallet.  Hello, everyone.  And welcome to this talk called Analyzing the Security of BGP Message Parsing.  So this talk will be presented by Daniel Dos Santos and myself, Simon Guillaume.  So first, a quick introduction.  The people that work on this vulnerability research project are Stanislav Dashevsky,  Amin Amri, and Oussama Kero.  And there's a direction of Daniel here.  And we are from the VDRE Labs team at Forthcote Technologies.  And our mission includes vulnerability research, threat research, and threat intelligence.  So now we're going to look at the relevant past research that we did.  So we had an initiative called Project Memoria, where we analyzed multiple TCP IP stacks that  we found in IoT and OT devices.  And in total, we found 61 vulnerabilities that we presented to the community previously.  And this inspired us to do this BGP research, because most of the issues we found were parsing  issues.  And we even published an informational RFC specifically about DNS implementations.  So first, Daniel will present to you what is BGP and how and where it is used.  Then I will talk more about the vulnerabilities we found and the methodology we used.  And we will conclude with the security implications.  So wait, hold on.  So I just heard a rumor.  You guys have never spoken here before.  Is that correct?  First time.  Yes.  What's the tradition for first time speakers at DEF CON?  All right.  Cool.  Thank you, Simone.  So let's talk a little bit about BGP.  And I do expect that a lot of people here will know at least that BGP exists and more  or less what it's used for and kind of what it looks like.  But I want to talk a little bit about different uses of BGP as well that people might not  be so much aware of.  So first of all, the internet in a nutshell, where is BGP used that everybody knows about?  You have edge devices on a network communicating to other edge devices on another network.  And those devices communicate via data packets that are routed from one network to another  via routers.  And those routers need to know how to get these packets from network A to network B.  And BGP is the routing protocol that allows these routers to exchange routing information  and kind of say, you know, I'm responsible for networks X, Y, and Z with this specific  IP block and so on.  And as Simone mentioned, we did some research in the past into TCP IP stacks and basically  the protocols used at the edge devices.  And now we wanted to focus on the router side of things and on BGP, right?  So BGP, routing for the internet, it's the protocol that is used to exchange routing  and reachability information among autonomous systems.  And an autonomous system is a block of IPs that is leased to an organization by a register  for a certain time period, right?  Just like you have in the domain name system, a domain is assigned to somebody for a certain  period of time.  Similarly, an autonomous system does that for a block of IPs.  So BGP is the protocol that is used to advertise autonomous system numbers and peer networks  that are considered to be part of an autonomous system.  And it can be either used internally within an autonomous system, so called internal BGP,  or externally called external BGP with peers on the internet.  And BGP is the protocol that makes routing decisions based on paths, network policies,  rule sets, and so on to kind of decide how a packet gets from one device in one network  to another device in a network all the way on the other side of the world, potentially.  But as I mentioned at the beginning, there are other use cases nowadays for BGP beyond  the typical network, internet scale routing.  So data centers in the past decade have grown to such a large size that many organizations  use BGP internally these days for routing internally in their own data centers, right?  BGP is also used for MPLS, layer 3 VPNs, across different organization sites.  So a same organization that has sites across the globe and wants to connect them via a  VPN, sometimes use BGP to exchange specific information for making that VPN possible.  It's also embedded in custom appliances that go sometimes in internet service providers  or internet exchanges.  Some content providers like Netflix, for instance, they have their specific way to treat traffic  and do that more efficiently, and they kind of embed these appliances directly in some  ISPs.  And, you know, there are emerging use cases like load balancing, and people get creative  and they're using BGP for a lot of other use cases these days.  So I just want to kind of open your mind to the fact that everything that we mentioned,  you know, BGP being used for the internet routing cases is the typical use case.  It's what it's mostly used for still these days, but there are many other uses for it.  So in summary, why I'm saying that is because BGP security per se is not just for internet  service providers and internet exchanges anymore, right?  Any organization will potentially be using BGP and should be responsible for the security  of BGP within their networks.  So the basics of BGP, right?  So BGP is a protocol with a kind of a simple state machine.  You have six states there, a limited set of messages that, you know, transition from  those states.  So basically you have peers that are waiting.  They set up a connection.  There is a keep-alive message that keeps that connection open that is sent every X seconds.  There is a notification when some error happens, or there's an update message to update the  routing tables between the peers.  And the packets are also relatively straightforward, right?  So you have a package that has a header with a length and a type of a message, and then  you have the content of the message, which is also not super complex, right?  So what potentially could go wrong with BGP?  So well, the fact, and going back to kind of the basics, and this is something that  is well known, that BGP, like DNS, like many other early internet protocols, has no built-in  security, right?  Like authentication, authorization mechanisms, and things like that.  So mistakes or intentional attacks that lead to network outages and traffic redirection  in BGP happen frequently, right?  The situation has been improving in past years, and we'll talk in the next slide a little  bit about some of the traditional routing BGP security, but the fact is that still thousands  of incidents happen per year of route leaks and hijacks, where basically a network or  a router originates in the BGP jargon, right?  So basically claims to be responsible for a prefix or a set of IPs that is owned by  a network, another network, without the permission of that other network, right?  And that, in some cases, is used by attackers to make packets go through specific networks  that an attacker controls and can maybe read or tamper with packets.  So in many cases, it's actually accidental, and in other cases, it potentially is an actual  attack, especially when countries or more riskier countries, let's say, are involved  in this kind of activity.  So traditional BGP security has to do mainly with filtering out this incorrect or malicious  routing information, doing origin validation, so verifying that a network that announces  a route is actually authorized to do it, and path validation, ensuring that no unauthorized  network is actually diverting traffic via a false route.  So there are many techniques, protocols, and ideas these days to do that, and I invite  you to have a look at those specific techniques, like RPKI, BGPsec, and so on.  But again, most of BGP security, until now, the typical discussion around BGP security  is always this kind of routing security, right?  But what about vulnerabilities in BGP implementations themselves?  So when BGP fails because of software implementations, it has happened in the past also, specific  incidents where, because of different implementations and the way that some BGP implementations  would parse messages, routers would actually crash and cause network outages and things  like that.  So a specific example that happened in 2019 with the FR routing BGP implementation, and  we're going to talk a little bit further about FR routing in the rest of this presentation,  it led to some network outages around Asia and Australia.  The fact was that some researchers were trying some new features in kind of an academic test,  but the fact is that not every router was ready to parse those new types of messages.  So why do we think it's important then to research these BGP implementations, right?  So the latest systematized work that we found about testing BGP implementations was 20 years  ago, actually, exactly 20 years ago in 2003.  It was a presentation at Black Hat, a team at Cisco that looked at both implementation  and configuration of BGP across different vendors.  They did the work that actually turned out in the end, we kind of followed some of their  paths.  So they created a fuzzer, they analyzed seven implementations and they found four new CVs  at that time, right?  But they also concluded that at that time misconfigurations were more dangerous than  actual implementation issues, and again, that was 20 years ago.  There has been a lot of improvement in BGP and in the actual implementation of BGP security  features in those 20 years, right?  Also in 2007, a team at Juniper analyzed specifically the update message handling across several  vendors, and they issued an advisory together with the third CC, and they saw that mishandling  of those update messages could lead to denials of service in several cases.  So they saw seven vendors affected, 10 not affected, and 25 that never responded to the  advisory.  And in the meantime, between that 2003 original research and now, those 20 years, we actually  found 129 CVs on BGP implementations.  We found, meaning those exist already, right?  Those were well-known.  We found in the National Vulnerability Database, and some of them include remote code executions.  So 95% of those vulnerabilities are actually because of message parsing issues.  So definitely it is a big problem in BGP implementations as well.  So if we drill down a little bit into these previous vulnerabilities, we see that there  is a mix of CVs on open and closed implementations of BGP, right?  So if you look, for instance, at Cisco and Juniper, the big networking vendors, of course  there have been CVs on equipment from those vendors.  But there is also implementations like the project I mentioned before, FR Routing, which  in the figure there, we actually put Quagga and FR Routing together, because Quagga is  the project that originated FR Routing.  FR Routing is a more recent fork of the Quagga project.  And again, just to make sure that we're all on the same page, the fact that Juniper and  Cisco are highlighted there with a higher number of vulnerabilities doesn't mean necessarily  that they are the most vulnerable, right?  It's just because they are vendors that actually issue CVs and they do their own research and  from time to time publish issues, and so potentially they are the more transparent, not necessarily  the more vulnerable.  But if we look at those CVs, those, again, 120-something in the past 20 years per impact,  we see that the vast majority of them allowed for denial of service.  Some of them also allowed for information leaks or remote code executions, but the vast  majority was denial of service.  And if we look at the timeline of disclosure for those vulnerabilities, we see that there  is an increasing interest starting more or less from 2017.  So from 2017 onwards, there is always at least around 15 vulnerabilities per year on BGP  implementations, popular BGP implementations being discovered.  So going beyond the vulnerabilities and into kind of the threat landscape per se, right?  So okay, we know that vulnerabilities exist, but still, why does it even matter to look  at these things?  So the first point is that threat actors are focusing on network infrastructure these days,  right?  This is something that, I mean, it always has happened, of course, but it has been intensifying.  And there are examples of nation-state actors, but also ransomware groups, other cyber criminals,  hacktivists, it's becoming more and more widespread and popular to go after network infrastructure,  things like routers, things like switches, firewalls, and so on that are kind of at the  perimeters of networks, right?  So recently, a couple of months ago, actually, CISA released a Biden operational directive  specifically about the risks of exposed management interfaces on network infrastructure devices,  right?  Because, partly because of this increased interest from threat actors into this kind  of device.  But still, there are several BGP implementations that were not systematically analyzed.  And as I mentioned in the previous slide, with some open implementations having vulnerabilities  found, those open implementations are becoming very popular these days and gaining a lot  of traction with a trend that is called network function disaggregation, NFD.  And basically, network function disaggregation is the fact that oftentimes these days, organizations  will use appliances or devices that, you know, the hardware comes from a vendor, the software  comes from another vendor, and things are kind of mixed and matched, right?  It's not always the same model where you had hardware, software, and everything coming  from the same major networking vendor.  And there are many different implementations of routing platforms, of network operating  systems, looking glass servers, and other routing components.  We specifically catalogued, sorry, 52 routing protocols, 40 of those are open, 12 are closed  protocols, 20 routing platforms, 17 of those were open, and 53 network operating systems,  and 20 of those were open.  So of course, we had to narrow down the research, right?  It's a lot.  Look at 53 different network operating systems.  So we kind of went after the most popular ones, and Simone is going to mention that  in the methodology part later on.  But going a little bit deeper even into the threat landscape and threat actors looking  into network infrastructure, as I mentioned before.  So CISA tracks, well, in May it was 925 non-exploited vulnerabilities, now it's probably a little  bit closer to 1,000.  And most of those affect traditional IT software, Windows, Linux, Mac, Adobe, and so on and  so on.  But 179 of those vulnerabilities can actually be mapped to specific devices that you will  have on your network.  And out of those, 88, or almost 50%, 49% of those 179 target specifically routers.  So they're the most popular type of device being actually attacked right now.  And yeah, I'm referring to another presentation there at Virus Bulletin in 2019 that talks  a little bit about this threat landscape for routers as well.  Have a look at that.  But the reasons are kind of obvious, right, why attackers would go after routers.  They are at the perimeter.  There are new vulnerabilities coming up all the time in routers, and they tend to be not  that difficult to exploit as, you know, exploit mitigations and things like that are not always  yet implemented in this type of device.  But again, drilling even further down, non-exploited vulnerabilities on BGP per se, right?  Out of those 88 vulnerabilities that we saw exploited in routers, three of those are decades  old CVEs affecting Cisco BGP devices that are being exploited in 2022.  So even if a vulnerability is, you know, from 2010 or 2009 or 2017, as in the cases there,  they are still being exploited up to this day, right?  There were also other two denial-of-service vulnerabilities on Cisco iOS, but those are  affecting a different protocol and not BGP, so we're focusing here on the BGP side.  And the interesting thing is, keep it in mind, Simone will make the connections here  later on, but keep it in mind that those vulnerabilities allow for denial-of-service, they are being  exploited by threat actors, and they have to do mostly with the parsing of open messages  in BGP implementations.  So let's talk about the new research that we've done.  So first let's talk about our methodology.  So as we said, we already did the prior work on vulnerability research, so we had already  some ideas, so mainly to look at the message parsing.  We also looked at the previous implementations where vulnerabilities were found, so we selected  all these implementations, and alongside we added the most popular implementations.  So this led us to have both open-source and closed-source targets.  And so we tried to start with static analysis, but of course for closed-source software it's  a lot more difficult, so we decided to try to develop a fuzzer that will help us in analyzing  these specific implementations.  And in the end we also used the fuzzer for open-source implementations.  So first the manual analysis we did led us to find multiple interesting things.  First we found some issues in the design of BGP, because it's a very old protocol, I think  the first RFC about BGP is from 1989.  So for example there is a lot of type length value parameters inside BGP messages, which  means that when doing parsing of BGP messages you first need to extract some fields to get  information on the next fields to extract, and it brings a lot of exception handling  and parsing quirks that make everything more difficult.  Also optional parameters are a mess, and another thing is that sometimes peer response to any  open messages.  So the open messages are the messages used to first establish a BGP connection, so it's  called BGP peering, and sometimes we even have update messages that are accepted by  peers without prior connection, BGP connection establishment.  So it's a big attack surface on the internet, and this is why we decided to focus mainly  on open and update messages.  So first for open messages we examined multiple implementations, we found two things, so first  most of the implementations they have the BGP running in the user mode, which means  that we first have the TCP connection establishment because TCP handshake is handled by the kernel,  so we cannot have filtering on the connections before looking at the BGP messages themselves,  but except for Cisco IOS where the BGP daemon is running in the kernel.  And so for one implementation in particular, so FA routing, we found that some parameters  are parsed before the origin of the messages is validated.  So we only had to spoof the source IP address to trace some attacks.  Now about the fuzzing, so first to explain quickly what is a fuzzer, it's basically a  program that will generate automatically malformed input to send to a target, and then we just  wait for the target to crash at some point.  And so in our case we used BooFuzz, which is an open source framework to make fuzzers,  and so with this fuzzer we only had to describe roughly what is BGP, like we did some test  cases by explaining to the fuzzer what BGP message looks like, so that it's able to generate  messages that look like BGP but are in fact malformed and contain possibly dangerous values.  And we also implemented an RPC monitor.  So the goal of the RPC monitor is to, we install it alongside of the BGP daemon, and so the  goal is to wait, because as soon as the BGP daemon will crash, the RPC monitor will report  the crash to the fuzzer, so the fuzzer will know that a specific payload made the daemon  crash and will save the payload and restart automatically the BGP daemon.  And it's open source, so if you want to contribute you can look at the code.  And so now for the demo of the fuzzer.  So on the terminal on the right you will have the BGP daemon running, and on the left you  will have the fuzzer.  So first we launch the BGP daemon, it's now waiting for connections.  Next we launch the fuzzer, and the fuzzer will just generate many malformed messages  attempting to crash the BGP daemon.  And it will soon crash.  So now the BGP daemon crashed, and we will see that the fuzzer generated a Python file  which contains the payload that made the BGP daemon crash.  And next we just have to launch the BGP daemon again, but this time inside the debugger,  so we can look at the specific issues that made the daemon crash.  So now we launch the BGP daemon inside the debugger, and it's now waiting for connections.  And now we will execute again the same payload that made it crash the first time.  Now it crashed again, and we will look at the backtrace to see in which function the  problem is.  And I don't know if you can see, but basically there's a function called BGP open receive,  which is a function that takes care of the open message parsing.  So with this fuzzer, we found in total three vulnerabilities, which are denial of service.  They are all due to the optional parameters in BGP.  They were quite easy to find, and they are similar to the Cisco IOS vulnerabilities that  Daniel introduced previously.  And also we wanted to mention that the FRO team were really quick in fixing the issues,  so it was really great working with them.  So for the first vulnerability, we have an if condition that will look if the optional  parameters are activated, basically.  And if they are activated, it will try to get the next byte in the packet, but without  checking beforehand if this next byte exists.  So we just had to send a packet that ends with the values that the if is looking for,  and we will get a read out of bound of one byte.  And just below in the same function, we have exactly the same issue two times.  The second vulnerability is again very similar, but this time we have a check to see if we  can read two bytes more.  But in case of optional parameter, we actually read three bytes instead of two, which is  again a read out of bounds.  And the third one is also the same.  It's a very similar code from the previous one, but it's in another function.  Right, thanks.  So kind of summarizing the results, or the new results, besides the things that I mentioned  before with previous vulnerabilities, so we do see that still there are some popular implementations  that are too permissive.  So in some cases, not necessarily filtering out correctly unwanted open messages.  And in other cases, even parsing these messages before filtering them, before discarding them,  before they actually realize whether it's coming from a wanted source or an unwanted  source.  On the other hand, some of this parsing can lead to denial of service vulnerabilities  and can be abused by attackers to take down some routers, sorry, some BGP implementations  on the routers and potentially the routing tables and so on.  So let's talk a little bit about the impact of these issues.  So any of these three new CVs leads to denial of service on a vulnerable BGP peer, as I  mentioned, dropping the BGP sessions and routing tables and rendering the peer unresponsive  for some time.  BGP is typically a daemon, so it will restart after a certain timeout, but this denial of  service can be prolonged by just repeatedly sending its one packet, right, that crashes  the server.  Two issues out of those three can be triggered before.  As I was mentioning, FRouting validates BGP identifier and ASN field, so even before knowing  if it's coming from a trusted peer, in a way.  So in this case, an attacker only needs to spoof a valid IP address to send this message.  And beyond these vulnerabilities, if we look at typical IPv4 scans, like show them the  figure that we have there, there are more than 330,000 hosts with BGP enabled on the  internet, more than 200,000 hosts that are running Quagga, the predecessor of FRouting.  Not all of those are running BGP necessarily, because Quagga is a routing suite that has  other protocol implementations.  And there are also more than 1,000 hosts running FRouting directly, right?  There are also implications of this type of vulnerability, because it deals with an open  source project, and because it's a component that will be embedded in other components  and so on.  There are kind of supply chain issues and supply chain implications here, right?  So if you take FRouting, it's an open source project that came from a previous project  that is even older, and it currently has more than 1,000 forks on GitHub.  So we worked very well with the project developers to fix it on the main branch of the project,  let's say.  But downstream forks, it's difficult to know when, how they will actually apply those patches.  Also, this type of component ends up in different network operating systems.  So I have some examples there, Dant, Sonic, Cumulus, they are popular network operating  systems that are also open source and use FRouting as a specific component.  So again, it's difficult to know when and which versions will actually apply those patches.  Those operating systems, in turn, are used by networking vendors, and that is what ends  up in the networks of end users, right?  So between the patches on the original project and the end users, there's a long way to go  before sometimes these patches are applied, right?  So almost any kind of research into vulnerabilities in open source these days has this kind of  consideration, right?  Supply chain is a big emerging issue, and we need to be aware of that.  But if we talk about risk mitigation also, I want to go back to the beginning of the  talk and say that routing security is still very important and still not solved, and specifically  for internet service providers or for people who are dealing with BGP on a day-to-day basis,  there are several good guides of security and basically good implementations of BGP  out there, right?  So Manners is a good project, there are specific RFCs for BGP operations and security, there  are guidelines from NIST and several other agencies about implementing the proper routing  security mechanisms.  But threat actors, as we mentioned in the beginning, have been attacking network infrastructure  devices directly, so don't forget software vulnerabilities, right?  That is specifically for BGP but also for other protocols, other implementations.  Those devices can be vulnerable, so you need to identify those devices on your network  that may be using BGP and assess those vulnerabilities and patch when possible, taking into account  all the supply chain issues that we mentioned.  Also the fuzzer that we released, it's open on GitHub and it comes with the prepared test  cases for the CVEs that we found, so if we want to test that against any implementation  that you have that is using FR routing for whatever reason, you can run those scripts  directly and if you want to test any new implementation, you're free and welcome to extend the fuzzer  as well or to use it out of the box on the implementation that you are interested in,  and we would really be glad to hear about results or ways to improve the fuzzer and so on.  So going to takeaways and future work, right?  So BGP is still crucial for the internet and it's widely used beyond internet service providers  and internet exchanges.  Unlike embedded TCP IP stacks, which we looked at in another project, BGP implementations  have matured very well and in general do not have obvious mistakes, right?  But some popular BGP implementations do have vulnerabilities or are too permissive.  That's the main conclusion here.  Network function disaggregation will make some BGP implementations, some open implementations  very popular that's already happening, so it's very important to keep the security of  those projects in check and keep doing research on those.  Threat actors are exploiting these kinds of issues and mitigation should not only be about  routing security and should not be only delegated to your ISP, right?  It's everyone's responsibility, let's say, to make sure that things are running securely.  In terms of future work, I think keep fuzzing new versions and new implementations, improving  the fuzzer with new test cases and so on is very important.  And exploring other parts of the routing infrastructure and the routing attack surface as well, like  other routing protocols, looking glass servers, remote control functions and so on is important.  And it would be very interesting to understand what specific for which campaigns these threat  actors are leveraging these BGP denials of service.  So that's it.  Thank you very much for your time and happy to take some questions now.


url: https://www.youtube.com/watch?v=TDMWejaucdg
title: DEF CON 31 - Revolutionizing ELF binary patching w Shiva - ElfMaster
type: video
author: DEFCONConference
ingestion_date: 2024-08-03
transcription_model: large-v2
content:
  {
    "webpage_url": "https://www.youtube.com/watch?v=TDMWejaucdg",
    "title": "DEF CON 31 - Revolutionizing ELF binary patching w Shiva   - ElfMaster",
    "description": "The esoteric art of patching ELF binaries has a long and fascinating history who's roots are deep within the hacking subculture; from ELF viruses to kernel rootkits. Silvio's 1997 \"UNIX Viruses\" paper taught us how to insert parasitic code into a page aligned text padding region. Many backdooring and hooking techniques have been revealed to us over the last 20 years-- perfect for hacking and injecting small patches and backdoors but on their own these techniques are limited, clunky and do not support the complexities of real-world patching problems in todays industry. Developers often need to fix complex bugs that exist within legacy ELF Binaries, no source code is available or the program cannot be recompiled.\n\nLet me introduce you to Shiva. Shiva is a JIT binary patching system for ELF; A custom ELF interpreter that loads and links ELF relocatable patches at runtime. Shiva allows developers to write patches in rich C code to naturally express the rewriting of binary code at runtime, in a high level language. ELF binary patching solutions over the past two decades have been scarce; some notable research: Katana and ERESI come to mind as pioneers in the early examples of custom ELF linkers and binary patchers.\n\nShiva is a next-level solution that allows developers to quickly write patches in C with little to no reversing knowledge. Born out of 16 years of ELF research into virus design, binary patching, and extensive experience with writing custom linkers and loaders.\n\nIn this talk we will discuss foundations of ELF binary patching and it's close relationship with ELF linkers, loaders and even ELF virus technology. This passionate body of research is combined and imbued into Shiva to create a highly innovative and powerful product that helps bridge the gap between Developers and Reverse engineers in modern binary patching solutions for ELF. A new workflow for maintaning insecure legacy software with modular patching capabilities is on the rise!\n\nPrepare for an indepth discussion of incredible new ELF hacking techniques and extensions. Old concepts such as userland-exec() brought back to life, and entirely new concepts such as \"Linker chaining\" to bring multiple dynamic linkers into a single process image. We will demonstrate complex patching scenarios, function splicing, program transformation, and even the weaponization of Shiva for writing sophisticated in-memory backdoors. Shiva; the ultimate ELF Binary hacker... aiming to solve the worlds most challenging binary patching problems today.",
    "channel_url": "https://www.youtube.com/channel/UC6Om9kAkl32dWlDSNlDS9Iw",
    "duration": 2748,
    "channel": "DEFCONConference",
    "uploader": "DEFCONConference",
    "upload_date": "20230915"
  }

  This text was transcribed using whisper model: large-v2

   Hey, guys. Thank you for coming to my talk. My name is Ryan O'Neill. My talk,  revolutionizing ELF binary patching with Shiva. So let me take a moment just to introduce  myself. My name is Ryan O'Neill. I'm also the author of the book Learning Linux Binary  Analysis, which is a book on ELF hacking and related topics. I've published in a lot of  journals over the years, different hacker journals, Frack, Pocker GTFO, VX Heaven, Temp  Out, and I'm also the founder of BitLackies.org, which is where I published a lot of my  independent research for many years, up until about 2019, still up. I'm also the founder of  Arcana Research, computer security research and development. This is actually this website  where you can read more about Shiva, arcanaresearch.io, and arcanatechnologies.io,  which is a Linux threat detection technology for detecting various types of threats within  ELF artifacts. Before I get too deep into the talk, I want to take a moment to talk about the  DARPA AMP program, since Shiva was in part born out of this program. This is a really unique  program created by Sergey Bratis. It's the Assured Micro-Patching Program by DARPA. This  program is really cool. It's all about taking some brilliant creative minds who want to  raise the state of the art in reverse engineering technologies and ELF binary patching  technologies. There's also an effort to be able to do formal verification of these patches,  so after the patch is installed, can it be called safe? There's a number of different  facets to the project, and throughout the number of different performers, there's quite a  number of CPU architectures that are being targeted right now, although I'm only  specifically talking about my project today. But just the AMP program as a whole is really  cool. What is Shiva? Shiva is a state of the art binary patching solution for ELF. It's  essentially a custom dynamic linker that's been highly specialized to load and relocate  object files and transform the program at runtime. I've written a lot of linkers and loaders  over the years, from computer viruses to kernel rootkits to all kinds of things, binary  protectors that require different types of custom linkers and loaders, and this is  definitely the pinnacle of my research after about 16 or 17 years of ELF binary hacking.  What makes Shiva special? Shiva has innovated quite a number of different new linking  concepts, so the ELF ABI has been extended to support more advanced linking and relocation  operations that allow for program transformation at runtime. Shiva's one of its  primary goals is to make patching binaries approachable, meaning you can do it in C, almost  just like you'd program anything else, trying to bridge the gap between the developer and the  reverse engineer, because patching binaries is often clunky and difficult. Shiva allows  developers to write nuanced patches with quite a bit of ease. So how can Shiva help you? So if  you're an organization or a company, generally speaking there's usually legacy software  that no longer has source code, and a bug comes up, whether it's a security vulnerability or  some kind of other bug, how does one fix that if there's no longer source code? And  oftentimes a team of people might get together to try to fix a simple bug, and it's  clunky, and there's no development workflow for that that's really been put into our  industry yet. So from a hacker's perspective, Shiva can do all kinds of things as well. It's an  advanced instrumentation engine. You can use it to create black box fuzzing harnesses. I used  it to fuzz the dynamic linker. One dynamic linker fuzzing another dynamic linker. But I  can't really get through a lot of the stuff I want to get through today, so I'm going to blast  through these slides, unfortunately, a little quicker than I might want. So the origins of  Shiva. About three and a half, four years ago I had an itch to write a custom elf interpreter.  Everybody here know what an elf interpreter is? Basically, usually the dynamic linker. But  writing an elf interpreter is an interesting thought, because, well, there's a lot of  innovative concepts that can be ignited through that. And so this led to a concept called  interpreter chaining, where I chained two dynamic linkers together into the same process  image, my custom dynamic linker, which was evil, and then the real dynamic linker. My  evil dynamic linker loaded a modular relocatable object virus into memory. So this was  actually my first implementation of a custom dynamic linker for elf or a custom elf  interpreter. And you can actually read that algorithm for interpreter chaining and the  whole virus and everything is published in temp out issue two, article six there. And  this modular elf virus loader interpreter ultimately morphed into the first version of  Shiva, which was originally for x86 64. I actually gave a talk about it a year ago, but  it's a completely different beast than what I'm talking about today. But just giving you a  little history there. And so the original Shiva was for loading elf micro programs. So it  was a custom dynamic linker that allowed you to load elf micro programs to implement  security features and such into the process address space, like control flow integrity  hardening or whatever. You can do a lot with it. It was an instrumentation dream toy for a  reverse engineer. And that's still available, actually just open source that today. We're  going to get into this in a moment here. But the current version of Shiva is Shiva alpha  version 0.11, and it was forked off that original version. So just to clarify. And it was  heavily modified to meet the requirements and needs of the DARPA AMP program,  specifically NASA. And so but with that said, it's I'm not going to get too far ahead  actually. So let me stick with the slide. So rewind 25 years. Who was originally trying to  patch elf binaries and for what purpose? And this brings us to the awesome era of early  Unix virus research. And Silvio Cesar, who is a good friend of mine and mentor, published  this research, you know, through about 97 to 99, this very early elf research, Unix and elf  parasites in 1998 and a number of other papers I could list. But you have to understand at  the time this was super esoteric stuff. Nobody was doing this in 98. Who the hell knew what  elf was? But I saw that paper when I was 15, and it definitely enamored me, compelled me  into wanting to work on that stuff. But yeah, just a ton of other research came after  this by various underground hackers and researchers, which we'll talk a little bit  about. But you know, it brings us to the concept of elf virus technology. It's really the  same thing as elf instrumentation coming from somebody who's written a number of  computer viruses for elf. The programmatic techniques that go into it are very much the  same as instrumenting a binary with any other code. Doesn't matter if it's a parasite or if  it's security code. Point is, you need to make room within the elf binary. Oftentimes the  techniques aren't trivial for restructuring a binary depending on the technique, you know,  text segment padding infection, reverse text infection. There's all kinds of ways. And then  that code has to be relinked in some way. Whether it's through PLT hooks, inline hooks,  relocation poisoning or some other means. Also we know that of course, you know, hackers  like to inject viruses into memory. So P-trace is often used. And it's often used for just  instrumentation in general. You look at many different technologies out there,  Dynamo Rio, a bunch of them use P-trace. I've used P-trace a bunch to instrument. But on the  same token, security technologies use this as well for injecting patches into memory or  instrumenting memory like Valgrind does. In ways it's similar to Valgrind in how it works in  terms of the just in time kind of aspect of it. Basically all the elf research was coming out  of the underground scene. In the late 90s and early 2000s, there were a few major players in  that area. One of them was the gruck. The gruck designed the user land exec implementation  which is a user land function that can execute another program. So you don't have to use the  exec v system call and drop into the kernel. One user land program can execute another user  land program. It has all kinds of insane uses. He was using it for anti‑forensics. I've used  it for binary protectors and now I'm using it for Shiva because it's a loader. So very, very  important research by the gruck. He did other cool stuff too. And of course we have Mayhem who  was the chief editor of frack around the time. And he had this incredible IRISI project, the elf  reverse engineering software interface which I really can't say enough about. Truly profound  work, especially in 2002. Just the sheer level of innovation and work that went into IRISI is  impressive. There's a number of other people that worked with Mayhem on that project, other  aspects of it. But very brilliant work and very influential. And then another really  influential piece of work that came from the early underground, probably 99, was Silvio's, he  wrote a version of insmod that could install a kernel module through dev KMM by handling all  the relocations and stuff manually. It was the first implementation I'd seen of a hacker  writing a linker or a loader at the time. But it really seemed very profound to me. And so  that's some really ‑‑ these are some real formative pieces of work that definitely  inspired me over the years. And there's also some really interesting stuff that's come from  the academic space in terms of elf binary patching. Firstly what comes to mind is Katana,  which is a Dwarf aware patching framework for elf. And it was designed by Sergey Bratis and  James Oakley, I think it was about 13 years ago. And a couple of really good white papers came  out of it. Pebble, I don't know as much about but I've kind of paid attention to it over the  years on GitHub. And it's an elf instrumentation framework. I think it's primarily used for  software profiling but it does some degree of function relocation. And then we have this  really great research called weird machines in elf by Rebecca Shapiro and Sergey Bratis. And  this was ‑‑ I think there was even a talk at DEF CON maybe in 2011. But it was all about  using the dynamic linker's relocation computations as a Turing complete machine. So you can  program the dynamic linker to do a lot. And just through metadata, you know, relocations,  whatever. And this is something Shiva does a lot. And so these are just ‑‑ yeah, this is  great stuff here. Take a look at some of the research tied to it. So, you know, we could say  elf binary instrumentation is a double edged sword. There's a lot to be learned from the  hackers and the underground community who are first putting this information out before 25  years later rolls around and here we are needing to design advanced binary patching  technologies. And Shiva has done that. But it's very much based in knowledge that I've  had preexisting in the underground scene. And so we're like, okay, binary patching is  pretty old. It goes all the way back to computer viruses. But really it goes back to the  beginning of elf which became the Unix standard in 1995 executable format for Unix,  Linux. And, you know, having been somebody who has done a lot of elf binary hacking over  the years, I put a lot of thought into this project. And I started, you know, looking at elf  and saying really it's already equipped mostly with what it needs. It's already equipped to  do a lot of patching just with its own relocation symbol information. And I started  looking at, you know, say LD Linux.SO. It's already a JIT micro patching engine. It does  simple patches but it's still a hot patching system. And then we have LD. LD links  relocatable objects into an executable using really granular elf relocation metadata. And  so just kind of looking and meditating on these things, how can I take what's already done so  beautifully and well and extrapolate on that to make an advanced binary patching system  that allows people to patch binaries and see? So I started realizing there's a lot of  power in writing an interpreter and what you can do with it. Started out as writing a  modular virus just to be, you know, cool and creative. But I knew it was going to  extrapolate into something a little bit more formal. And so you guys, most of you  probably familiar with elf. The PT interp segment holds the path to LD Linux.SO or the  dynamic linker. That gets replaced with lib Shiva. And the interpreter, generally  speaking, sets up the finer details of the process image. And the interpreter has  instrumentation precedence because it runs before even the real dynamic linker. So  another strong aspect of it is, you know, patching memory with P trace is slow because  you're in another process and there's a lot of context switching and things that  happen. If the patching, you know, engine is in the same address space of the program  it's patching, it's much faster. And so this is something exploring a different time and  more depth. But essentially I started thinking, well, an elf relocatable objects have  really great metadata, enough relocation information to build a process image out of.  And so really Shiva is somewhat of a hybrid between LD and LD Linux.SO. So it draws  wisdom from both linkers. It's flexible, it's modular, like the dynamic linker, LD  Linux.SO, but it has the nuance of LD because it uses that really granular relocation  information that's in those elf object files. So to kind of further just show how it fits  into the existing elf linking components, you've got LD, it's an elf linker. You've got LD  Linux.SO, that's a linker and a loader because it loads shared libraries and knows how to  load executables. And then you have LibShiva, which is an elf linker, loader and a  transformer. And we're going to get more into transformation, transforms, how they fit on  top of relocations a little bit later. But, or maybe right now. So Shiva's innovation in  linking concepts. Shiva, just in the research and development of it, you know, I created a  number of new techniques that are necessary to kind of bring this all together. One of them  I touched on briefly, interpreter chaining, elf transforms. In fact, I'm not even going to go  through the whole list right now. But each one of these is something that's either brand new  or being used in a new way. Generally this is all pretty new concepts that fit really nicely  into the existing elf ABI. And we're going to talk deeper about them. Shiva's built on top  of LibElfMaster. It's a library I wrote in like 2018. It forensically reconstructs broken  binaries under the hood. So if a binary has no section headers or symbol tables, it will  reconstruct those based on the EH frame, the dynamic segment, other things, and recreate the  symbol table internally. So even though Shiva is symbolically driven, it can still work on  stripped binaries because of that. So I thought that might be a question that comes up. So let's  take a look at Shiva's elf linking workflow. So on the very left we have just two object  files, main.o and foo.o being linked into a program, my program. In the middle we see that  that program is now being executed and it has the LD Linux interpreter loading libc.so into  memory. That's just the general kind of linking workflow. You move over to the very far right  and there's a diagram illustrating that Shiva and LD Linux.so are cooperating together in  the same address space to transform the program with both the patch and the shared  libraries. So the standard elf dynamic linking workflow essentially looks like this. The  kernel is trying to execute a program called test. But first it loads test interpreter, which  is LD Linux.so, passes control to it. The dynamic linker loads libc or whatever it's loading  and then passes control to bin test. Actually passes control to the underscore start  function. With linker chaining where you're linking multiple dynamic linkers into the same  address space, you have both lib Shiva and LD Linux.so cooperating together. The kernel  loads Shiva since that's the interpreter. Passes control to it. Shiva loads, links and  transforms this patch and then it actually user land execs essentially LD Linux.so into  memory. Maps all the segments into memory. Passes control to the real dynamic linker just like  the kernel would. The dynamic linker then loads its shared libraries and then finally passes  control to test. That's actually a simple, simple workflow. We'll get deeper later. But I  mentioned elf patches are compiled as just regular relocatable objects. You can use clang  or GCC. In the future I plan to write a compiler wrapper. But essentially, you know,  relocatable objects are great for patches. They contain rich symbolic metadata for both  relocations, all the symbol names. And I have extended some of it, but generally speaking the  object files are really nice. You have to build them with a large code model. That way an  internal got is used for absolute addresses so that you don't run into a situation where you're  further than four gigabytes away from the executable that you need to relink with. So  there's that. But I definitely recommend checking out the Shiva module loader function in  Shiva underscore module dot C. It's definitely where all the most probably interesting code  is. Also, you know, after an elf relocatable object is, so an elf relocatable object basically  gets loaded into memory. Shiva creates a text segment, data segment, BSS for all the patch  information. All the sections are put in their appropriate places. All the relocations for  the patches are handled. But then the executable itself needs to be relinked to use the new  patch code and data. Well, that's a little difficult because elf executables don't have  relocation data that describe how to relocate their own text section. They have a little bit  of dynamic linking information, but that's different. They don't have the information that  was in the original elf object files because it's not needed anymore. It would be nice. But  what Shiva does is it generates a control flow graph and based off that it generates  relocations on the fly for the elf executable because there's a lot of relinking and  reencoding of instructions that has to be done if you splice new code in, for instance. All  the offsets change. Everything changes. And so we're able to handle all that pretty nicely,  fluently. So I mentioned briefly Shiva's userland exec functionality. This is just used  kind of like any interpreter with Python. You can call Python directly. Same with Shiva.  This is really good for testing a patch. Let's say you want to make no metadata  modifications to the binary. Just leave the binary completely untouched. You just specify the  patch object in the Shiva module path environment variable and then you run Shiva and then  the program you're trying to execute. And it will load and install the patches all at  run time. If you want the program to be patched every time you run it without having to  execute Shiva, you have to use the Shiva prelinker. We'll get into that in a minute. But it  updates the PT interp segment with the correct interpreter and also adds a new dynamic  segment. A couple other little things. So can everybody see here the requesting program  interpreter is Lib Shiva in this program instead of LD Linux? So that's just kind of  illustrating for you what the program looks like after it's been prelinked. And then if the  dynamic segment here, we can see the last three entries towards the bottom here, Shiva  needed. And I don't know why you can't see that. Hold on here. There's like something in  front of it there. But that's the base name to the patch object Shiva needed. So the  needed patch objects. The search right here is the search path to where all the object files  are stored. Just like with the dynamic linker, they're usually stored in Lib. And then it  gives the path to the original ELF interpreter so that Shiva knows which path the  interpreter is to load and link into memory because it will map the dynamic linker into  memory once it's done. So I want to talk about ELF symbol interposition here for a  moment. So is anybody familiar with what that term means? ELF symbol interposition?  Okay, yeah. So essentially though, think LD preload. It's where you can overwrite one  symbol with another symbol because it has the same name based on the precedence of the  object that's loaded. So Shiva, one of its really strong features is that it allows you to  rewrite any code and data just by name. As long as there's symbolic data attached to it,  any global data, any global functions, even local functions, although it needs about two  days of work to do that. But essentially anything symbolically can be rewritten. It's  actually really easy. So instead of just rewriting functions like with LD preload, you  can rewrite anything by name essentially in the executable itself. I want to give just a  little example here. See we're running hello. It says hello world. Can you guys see that  okay? It's kind of small. And then I look at the symbol table and I see there's a string  called hello underscore string that lives in the RO data section. And if we, let's say we  want to change that program. The program's called hello. And we want to make it so that it  prints hello DEF CON 31. So we literally have a very simple patch. We just redefine that  constant string by name. We compile it into an ELF relocatable object with a large code  model. And then on this slide we're going to show you how it works. So running hello just  runs hello world. But if we set the Shiva module path to the patch object and then run  Shiva on hello, it installs the patch at run time. But then if you just run it without  Shiva it just goes back to normal. So this is a great way to test things or just if you  only want to do things once or dynamically. Generally speaking though, most people want  to patch their program permanently. So what you do is you use the Shiva prelinker. It's  called Shiva LD. And it essentially just installs the original interpreter information,  the patch metadata such as the location of the patch into the new data segment that it  creates in the binary. So the executable code and data isn't changed at all. It's just  metadata. So that the new binary uses the correct interpreter path and all that. So we  can see we run hello directly now that we prelinked it and it's printing hello DEF CON 31.  So just a simple patch and see. So transformations. I mentioned these earlier. So this is  transformations begin where relocations leave off. I think the dynamic linker is just  brilliant. It's a brilliant hot patching mechanism. We can learn a lot from it. Why not take it  and utilize it for micro patching binaries. Something of that nature. The same concept.  Extrapolating on it. So if ELF relocations are the metadata that describes simple patching  operations, then ELF transformations would be the metadata that describes complex patching  operations. Such as function splicing. Things of that nature. So function splicing is the  ability to splice C code into any function at any given point within the function. Fully  relocatable code, fully symbolically rich access to all the shared libraries, symbols,  functions. And this is very complicated. There's a lot of relinking. Many, many magical  things have to happen under the hood. But the end result is that we have these transform  macros that developers can use to splice code in and out of a function. So this is just  a kind of a crude example here. But essentially we have on the left a program that you  stir copy. And it's a function called copy string. And let's say we want to modify that  function so that it uses stern copy. Make sure the string buffer is null terminated. So on  the left you can see the code that's being removed from 7BC down to 7C8. Which will make  our stopping address 7CC by the way. But we want to splice this code which is larger into  this little area there. We want to make it look like this on the right. So how would we do  that? So this is actually a transformation patch right here. Giving an example. So up here we  have this macro. Shiva T splice function. Copy string. And remember I gave you the offset  7BC to 7CC. Now these three lines of code are pretty simple. The first line because the  argument stored in the X zero register because it's ARM. We create a source pointer  variable because it's the argument of the function copy string. And then the destination  buffer was at base pointer plus 32. So Shiva gives you macros to access live variables and  registers as needed. And then it just does stern copy. This actually compiles into an  object file that looks like this. And unfortunately I don't have all the time I'd like to go  on that tangent. But generally speaking in the text section here we have this function.  Shiva splice FN name copy string. That tells Shiva okay this function right here is actually  code that's going to be spliced into a function called copy string. By the way it won't  copy the procedure prologue and epilogue. That's not splice code. But ARM doesn't  respect the naked attribute apparently. So overflow crashes. Okay so this is a program  called overflow. It's the one that I showed you. It's vulnerable. It's got stern copy. We  can see that when we pass it four A's it works. When we pass it like over 16 A's it crashes.  So we pre link our patch. This one I showed you right here that we compile into a  relocatable object. Pre link it to the vulnerable program overflow. And then we run  overflow and we can see that it works. It's not crashing anymore. That's because it's using  stern copy and properly null terminating the string. But just showing how that's a very  simple example. You can splice into any function. That's just to make it palatable in a talk.  So spliceable code has some interesting characteristics. I kind of covered some of them.  It's fully relocatable. A very rich symbolic access with natural C development. There's no  limit or size to the amount of code you can splice into an existing function. And yeah, I  mean you can ‑‑ and then of course there's macros for gaining access to live variables and  registers on the stack and whatnot. So confluent linking technologies. This is a  terminology I've kind of coined which just means two dynamic linkers working together  coherently within one process image to build, transform and re‑link the program at run  time. And there are a lot of cases ‑‑ so there's a couple new things here. Cross  relocations. This is actually where one dynamic linker relies on another dynamic linker to  solve its own relocation. So an example of this is let's say you write a patch that has a  new BSS variable. It's overwriting another BSS variable in the original program. This is  the new version of the variable that should be used. Maybe you had to extend a buffer size  or something. Those BSS variables are often accessed indirectly through the got. There's a  relative relocation, at least in pi executables, that fixes up the got to the correct BSS  address. So when Shiva ‑‑ when somebody has a patch with a new BSS variable, for  instance, they will ‑‑ sorry, I'm looking at the time here. They will ‑‑ Shiva will  instruct the other dynamic linker to essentially patch it by modifying the relocation  metadata in memory. So you can basically tell the dynamic linker to do whatever you want. You  give it a script. The script is the ELF sections that ‑‑ and the values in the dynamic  segment that are read by the dynamic linker. We also have delayed relocations, which we  therefore we have the Shiva post linker, which actually handles some relocations after  LDLinux.SO. So Shiva will load, link the patch, pass control to the dynamic linker. And  then when the dynamic linker is done, oftentimes it passes control back to a function called  Shiva post linker. We actually update the AT entry value in the auxiliary vector, which  normally points to the start function of the program, so that it jumps back to the Shiva  post linker. The Shiva post linker then finishes handling any delayed relocations and then  passes control forward. Shiva was just made open source today. I am excited, grateful to be  able to share it with everybody. Please ‑‑ and there's a user manual. There's quite a bit of  documentation. But let's see. What time is it here? So let me go into this demo real quick for  you guys, okay? I want to ‑‑ all right. I hope you like Chopin. All right. So I want to  illustrate an example of symbol interposition and how it can be used to rewrite global code  and data on the fly with Shiva in a way that's natural for C developers. So let's take a  look at this simple program test foo. And for the sake of illustrating the scenario, I'm  going to show you the original source code. So we can see that main simply calls foo and  then prints the return value. Foo prints I am the original foo function and then it prints  the value of lucky number. Lucky number is an initialized global variable, so it would  live in the data section. So let's say we wanted to rewrite this function and also print  and modify this variable. In fact, we actually want to redeclare this variable. Let's take a  look over here on the right side of the screen. And this is the actual patch code itself. So as  you can see, we've redeclared lucky number as an uninitialized global variable. In Shiva we  call this, you know, redefinition or redeclaration of storage type or storage type  redeclaration. And then down here we have rewritten foo. And this is showing how we can drive our  patching through symbolic references. So these symbols exist within the target binary and so  we're able to rewrite them using symbol interposition. Now, right here we set the value of  lucky number. It's now initialized to 31337. We print I am the new function foo. We print the  value of lucky number. And then right here we're demonstrating how Shiva patches are able to  resolve shared library functions that don't already have a PLT entry in the executable that  we're patching. And so right here we're calling system to cat this Shiva dot ANSI file and then  we return dead beef. So we have rewritten foo and we have redeclared lucky number as an  uninitialized variable. So let's say we want to take this patch and we want to compile it. So we  would, sorry, we would build it just like a relocatable object with a large code model, which  we have to use no pick and then, so we have a relocatable object and we have a large code  model. So this is the object now. You can see the locations in it. Symbol table. And if we want  to install this patch, there's two ways to do it. So firstly, in many cases we just want to try  the patch out or just test it once without making any modification at all to the target binary.  And so test foo without a patch. And now test foo with a patch. We specify the Shiva module path  environment variable. Export it. And then we simply invoke Shiva directly. And now it runs the  patch version. So it has been, the executable has been relinked in memory to use the code and data  specified in our patch. Prints I am the new function foo. It then prints 31337 is the lucky  number. It prints the Shiva ANSI banner and then prints the return value of dead beef. Now if we  wanted to install this patch permanently, we would have to use the Shiva pre-linker, which installs  some metadata such as the path to Shiva into the insert segment and it updates the dynamic segment  of the executable and adds a few new entries. So let's take a look at that. Let me clear the  screen. Shiva LD works like this. And so I'll give an example. Dash E is the executable, which is  test foo. The patch base name is foopatch.o. The interpreter path is libshiva and the search path  is optshiva modules. And then we'll rename it the same name. So test foo with a patch. And then  if we were to look at the program segments of test foo, we can see that libshiva is now the  interpreter. We also see there's an extra load segment there and that's to make room for the new  dynamic segment. So let's take a look at the dynamic segment and how it's been modified. So the  dynamic segment is actually the same except it has three new entries at the bottom here, which a  readelf hasn't been modified to print what these are. But this is the addresses to the patch base  address to the patch search path, and then the address to the path of the original interpreter,  which is ldlinux.so. And we also have to move the patch or copy the patch into the optshiva  modules directory because that's the search path that we specified. So in any case, now when we  run test foo, it's patched every single time because of that metadata that's been installed. The  only difference between test foo now and before is that the dynamic segment's been updated and the  PT insert segment has been updated. And so another neat little feature is if you call shiva  directly again with the dash U flag on test foo, we'll actually run test foo and it will run it  without installing all the patches. So that's kind of a neat feature. And next we're going to  look at transformations with function splicing.  Thank you. There's more. Appreciate it. Thank you. Okay. So I'm going to try to  demonstrate elf transformations as concisely as I can in this example with a program called  testprog. So let's take a quick look at the original source code. So we have this function  foo here. Foo is called down here in main. And foo says if this first argument num is equal to  seven, then go to done. Otherwise, copy banner, which is this const pointer to the string  elf master over into global buff. Global buff is a BSS buffer. And then it prints the value of  this argument string. And so what we want to do here is actually overwrite this function called  printf with some code that first checks to see if str is equal to null. And if it's not, then it  will print it. And then also we want our code, our patch code to print the value of global buff.  And so let's take a look here. There's a number of things happening in this patch. So we're  actually going to start at the bottom. So firstly, over here on the left in the original source,  we have bar. And in our patch code, we rewrite bar. As we can see, it adds the value of two  variables that were added in this patch, this data val. It adds the variables together and then  prints the sum. And then up here, so bar is being completely rewritten with symbol interposition.  And then moving up here, we have the actual splice code, the splice patch. This is how  transformations work when developing Sheba patches that need to splice code into an existing  function. And so this macro right here is used. So we are splicing into the function foo.  The address to start patching at is 818, and the stop address is 828. And so coming down  into the actual splice code, let's start right here. We have if str is not equal to null,  then print the string. And if you notice, we're using fprintf instead of printf, which was in the  original program. And this is, again, just illustrating strong global symbol resolution. And then  after that, we use fprintf to print the value of global buff, which illustrates our patch ability to  use the extern keyword. So we're using the extern keyword to get a hold of global buff, which is a  global variable from the program that we're patching. And so after that, we call bar. And this is  where we'll link to the new function bar instead of the original function bar. And when main calls  bar, it will also link to our new function bar, of course. Anyhow, so back up to this transformation  macro, we want to patch at 818. Let's take a quick look at why. So we'll look at the program  assembly down here at function foo. We're going to be patching from here to here. Actually, to right  here. So our start address is 818. And the last address that we patch is 824, which makes our stop  address 828. And 828 and all of the code after it will be shifted forward as needed based on the size  of the code being spliced in. And in our case, we're splicing a larger amount of code in. Let's just  build our patch real quickly. And now we have a relocatable object called patch.o. These are the  relocations for it. And if we look at user object dump, you can see this is the splice code, this  whole function right here. And you can see it uses a special symbol name called Shiva splice FN name  and then the function that's being spliced as foo. This directs Shiva to use the function splicing  and so Shiva will splice all of this code in. The procedure prologue and epilogue won't be included.  All of this code will be relocated and transformed essentially. It will be inserted and spliced into  the function foo again into this location right here. So we're actually adding quite a bit of code.  And so this will rewrite the entire function foo. It will actually be rewritten from scratch in a  different area in memory. And the reason that in the source code I included this if num is equal to  seven, go to done, is to illustrate how it will have to be, the assembly code for that will have to  be relinked in the binary or in memory once our patch code is inserted here because the patch code  is much larger. And so for this to jump down to done, the offsets will change. So this also,  patching this program also illustrates Shiva's ability to relink the executable as needed when the  patch code extends the size of the function. And this works by Shiva generating on the fly  relocations for the executable by looking at a control flow graph. And so anyhow, let's just try to  install this patch and see how it works. So again, testprog looks like this when we run it.  Now let's install the patch dynamically. We'll just run Shiva directly. The patch is patch.o.  Patch.o and the Shiva will run Shiva directly and execute testprog.  And now we see it's working as expected. It only prints the argument we pass it when we actually pass  it an argument. Let's see. And if we don't pass it an argument, it doesn't. And if we put seven  arguments, it jumps right down to done and doesn't print, doesn't do any of the other stuff that it  was doing. So it's actually working exactly how we modified the program to behave. Now again, if we  run testprog without Shiva, it still does the same old behavior. If we want to link the program  permanently, then we use the Shiva prelinker as demonstrated before. Shiva is the interpreter.  The search path is opShivaModules. The output is testprog. We need to copy the patch into opShivaModules  just the same way we'd copy a shared object into the lib directory. So now when we run Shiva  directly, or I mean when we run the program directly, it works every time it's patched. And again,  the program's metadata has been modified. We can see libShiva is the interpreter, et cetera. So that  is function splicing. Yes. Thank you. What happened to my slides there? Oh, there we go.  So I've got a couple of minutes left here. Let me pop the slides back up. I'm not real familiar  with Adobe. But whatever the case, let's see here. Sorry. I'm not familiar with Adobe. I'm  not familiar with Adobe. I don't know. Yeah, let me. I have a good idea here. Well, there  really wasn't. There's one last slide here. Give me just a moment. What's that? Control L.  Well, yes. Thank you. Look at me. Here I am. Okay. There's one last slide that I would like to  just leave up for a moment if I could. So I guess you can specify the slides. I'm not familiar  with slide two. I think it's like slide 51 that I'm looking for. Ah, there you go. Okay.  Up until 51. Just close your eyes. I don't want to cause any seizures. All right. Thank you.  So firstly, I just want to say thank you to my son, Jayden, for helping me with the video  editing. It's not my strong suit for the demo. Thank you, Jayden. Appreciate that.  He tries on YouTube. And I want to say thank you to my wife, Teresa O'Neill, for being such a  powerhouse behind me. Thank you, honey. And my mother. My mother bought me every book by  Richard Stevenson by the time I was about 16. I had them all. Unix Network Programming.  She was on it to help me get educated on what I wanted to learn. So thanks, Mom. Love you.  And thanks to my son, Mick, for being here. He just turned 18. So super grateful to have my  son with me. And super grateful to be able to share this with you guys. I have open sourced it  today. I'm sure email me if you have any problems. There's the Shiva user manual. It's still a  work in progress. But it gets deeper. There's also some design specifications that are in the  Shiva repository. They're a little behind date. But if you want to learn more about it, go to  the website, ArcanaResearch.io, Shiva. And feel free to reach out to me for any questions  about it. And thank you. Grateful for everybody being present. Is there any questions for 30  seconds? You got three seconds. All right.  All right.


