## https://sploitus.com/exploit?id=DB1B59CE-B573-5463-A377-0B858903FF7D
# CVE-2026-39973-PoC
This is a small C# apk file builder for [CVE-2026-39973](https://github.com/advisories/GHSA-m8mh-x359-vm8m).
## Credits
- [OnlyToxi](https://github.com/onlytoxi) - Helping with the path (will be helping further) & emotional support.
- [iBotPeaches/Apktool](https://github.com/iBotPeaches) - Documentation & parsing.
## Disclaimer
- This is a **proof of concept**, which is made for educational purposes only!
- AI has **NOT** been used (except for small questions about serialization) while writing this code or this documentation.
- My knowledge is **LIMITED**. This is my first CVE PoC. The documentation may be wrong or incomplete.
- The code may be difficult to read since I was in a hurry and sleep deprived (sorry).
# CVE-2026-39973
[CVE-2026-39973](https://github.com/iBotPeaches/Apktool/security/advisories/GHSA-m8mh-x359-vm8m) is a path traversal vulnerability within the github repo [iBotPeaches/Apktool](https://github.com/iBotPeaches) affecting version 3.0.1.
It allows attackers to create their own resources and inject a `..\` sqeunece within an entry's type, allowing a threat actor to write any file to `~/.bashrc` or the Windows startup path.
## Security regression
This vulnerability comes from a security regression in commit [e10a045](https://github.com/iBotPeaches/Apktool/commit/e10a0450c7afcd9462c0b76bcbff0e7428b92bdd) (PR [#4041](https://github.com/iBotPeaches/Apktool/pull/4041)) which removes `BrutIO.detectPossibleDirectoryTraversal()` from `ResFileDecoder.java`
**ResFileDecoder.java#L103-L109 BEFORE:**
```java
String outResPath = entry.getTypeName() + entry.getConfig().getQualifiers() + "/" + entry.getName();
if (BrutIO.detectPossibleDirectoryTraversal(outResPath)) {
LOGGER.warning("Potentially malicious file path: " + outResPath + ", using instead: " + inResPath);
outResPath = inResPath;
} else if (!ext.isEmpty()) {
outResPath += "." + ext;
}
```
**ResFileDecoder.java#L103-L104 AFTER:**
```java
String outResPath = entry.getTypeName() + entry.getConfig().getQualifiers() + "/" + entry.getName()
+ (ext.isEmpty() ? "" : "." + ext);
```
This commit removed a judged "useless" check on the whole output path As `entry.name` was already [checked beforehand](https://github.com/iBotPeaches/Apktool/blob/main/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/table/ResEntrySpec.java#L36) (`ResEntrySpec` constructor).
The author forgot that the entry's Type name could be subject to a path traversal by crafting our own malicious `resources.arsc`.
## Resources.arsc
`resources.arsc` is a file containing the resource data, paths, type names and more.
It stores all we need to be able to modify the type name or craft a `resource.arsc` file to exploit Apktool.
Despice its reccurence, i've only found [poor but satisfying documentation](https://apktool.org/wiki/advanced/resources-arsc/) on the serialization.
**At this point, it is strongly reccomended to read apktool's [documentation]((https://apktool.org/wiki/advanced/resources-arsc/)).**
I started basing myself off Apktool directly as I'm gonna need to build a `resources.arsc` file for this application exclusively.
I downloaded a random APK file off of the internet and opened it with 7zip. Then I extracted the `resources.arsc` file and started studying the data structures along with Apktool's parser code.
Then I made a small C# builder for the resources.arsc file, writing a `ResTable` and a `ResPackage` with one `ResType` which has the `..\` sequence and the path of Windows Startup folder, it also has one entry which is the payload file.