Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tainted data does not flow through a reflected class. #156

Open
adityavardhanpadala opened this issue Mar 19, 2024 · 1 comment
Open

Tainted data does not flow through a reflected class. #156

adityavardhanpadala opened this issue Mar 19, 2024 · 1 comment

Comments

@adityavardhanpadala
Copy link

Bug

Bug description
Tainted data does not flow through a reflected class when reflectedmethod.invoke(Object, Object) is executed.

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		try {
			TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
			String imei = telephonyManager.getDeviceId(); //source

			Class c = Class.forName("de.ecspride.ReflectiveClass");
			Object o = c.newInstance();
			Method m = c.getMethod("setIme" + "i", String.class);
			m.invoke(o, imei);
			
			Method m2 = c.getMethod("getImei");
			String s = (String) m2.invoke(o);
			
			SmsManager sms = SmsManager.getDefault();
	        sms.sendTextMessage("+49 1234", null, s, null, null);   //sink, leak
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

Reproduction steps
The apk is from DroidBench
https://github.com/secure-software-engineering/DroidBench/blob/master/apk/Reflection/Reflection3.apk

Sink Model:

    {
      "find": "methods",
      "where": [
        {
          "constraint": "signature_match",
          "parent": "Landroid/telephony/SmsManager;",
          "name": "sendTextMessage"
        }
      ],
      "model": {
        "for_all_parameters": [
          {
            "variable": "idx",
            "where": [],
            "sinks": [
              {
                "kind": "TaintedSmsSink",
                "port": "Argument(idx)"
              }
            ]
          }
        ]
      },
      "verbosity": 2
    },

Source Model:

{
  "model_generators": [
    {
      "find": "methods",
      "where": [
        {
          "constraint": "signature_match",
          "parent": "Landroid/telephony/TelephonyManager;",
          "name": "getDeviceId"
        }
      ],
      "model": {
        "sources": [
          {
            "kind": "TaintedSource",
            "port": "Return"
          }
        ]
      },
      "verbosity": 2
    }
  ]
}

Logs
Log file with the logging for onCreate method.
log.txt

@arthaud
Copy link
Contributor

arthaud commented Mar 20, 2024

Mariana Trench won't resolve calls using reflection, since the name can be anything at runtime.
In this specific example, we could detect that the argument is always "setImei" and call the right method. We don't currently support that, since we haven't seen this used frequently.
If you want a work around, you could model Method.invoke to have a propagation from Arg(2) -> Arg(1), so imei taints o.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants